mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-06 17:28:29 +08:00

committed by
GitHub

parent
46d9827960
commit
f820dc144d
@ -79,7 +79,7 @@ export function test_PlayRejectsWhenAlreadyPlayingAnimation(done) {
|
|||||||
if (e === 'Animation is already playing.') {
|
if (e === 'Animation is already playing.') {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +164,8 @@ export function test_ChainingAnimations(done) {
|
|||||||
.then(() => label.animate({ translate: { x: 0, y: 0 }, duration: duration }))
|
.then(() => label.animate({ translate: { x: 0, y: 0 }, duration: duration }))
|
||||||
.then(() => label.animate({ scale: { x: 5, y: 5 }, duration: duration }))
|
.then(() => label.animate({ scale: { x: 5, y: 5 }, duration: duration }))
|
||||||
.then(() => label.animate({ scale: { x: 1, y: 1 }, duration: duration }))
|
.then(() => label.animate({ scale: { x: 1, y: 1 }, duration: duration }))
|
||||||
.then(() => label.animate({ rotate: { x: 90, y: 0, z: 180 }, duration: duration }))
|
.then(() => label.animate({ rotate: 180, duration: duration }))
|
||||||
.then(() => label.animate({ rotate: { x: 0, y: 0, z: 0 }, duration: duration }))
|
.then(() => label.animate({ rotate: 0, duration: duration }))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
//console.log("Animation finished");
|
//console.log("Animation finished");
|
||||||
// >> (hide)
|
// >> (hide)
|
||||||
@ -610,7 +610,7 @@ export function test_PlayPromiseIsResolvedWhenAnimationFinishes(done) {
|
|||||||
function onRejected(e) {
|
function onRejected(e) {
|
||||||
TKUnit.assert(false, 'Animation play promise should be resolved, not rejected.');
|
TKUnit.assert(false, 'Animation play promise should be resolved, not rejected.');
|
||||||
done(e);
|
done(e);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,7 +627,7 @@ export function test_PlayPromiseIsRejectedWhenAnimationIsCancelled(done) {
|
|||||||
function onRejected(e) {
|
function onRejected(e) {
|
||||||
TKUnit.assert(animation.isPlaying === false, 'Animation.isPlaying should be false when animation play promise is rejected.');
|
TKUnit.assert(animation.isPlaying === false, 'Animation.isPlaying should be false when animation play promise is rejected.');
|
||||||
done();
|
done();
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
animation.cancel();
|
animation.cancel();
|
||||||
|
@ -79,8 +79,8 @@ class AnimationDelegateImpl extends NSObject implements CAAnimationDelegate {
|
|||||||
targetStyle[setLocal ? widthProperty.name : widthProperty.keyframe] = value;
|
targetStyle[setLocal ? widthProperty.name : widthProperty.keyframe] = value;
|
||||||
break;
|
break;
|
||||||
case Properties.scale:
|
case Properties.scale:
|
||||||
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x === 0 ? 1e-6 : value.x;
|
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x === 0 ? 0.001 : value.x;
|
||||||
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y === 0 ? 1e-6 : value.y;
|
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y === 0 ? 0.001 : value.y;
|
||||||
break;
|
break;
|
||||||
case _transform:
|
case _transform:
|
||||||
if (value[Properties.translate] !== undefined) {
|
if (value[Properties.translate] !== undefined) {
|
||||||
@ -95,8 +95,8 @@ class AnimationDelegateImpl extends NSObject implements CAAnimationDelegate {
|
|||||||
if (value[Properties.scale] !== undefined) {
|
if (value[Properties.scale] !== undefined) {
|
||||||
const x = value[Properties.scale].x;
|
const x = value[Properties.scale].x;
|
||||||
const y = value[Properties.scale].y;
|
const y = value[Properties.scale].y;
|
||||||
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = x === 0 ? 1e-6 : x;
|
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = x === 0 ? 0.001 : x;
|
||||||
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = y === 0 ? 1e-6 : y;
|
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = y === 0 ? 0.001 : y;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -309,6 +309,7 @@ export class Animation extends AnimationBase {
|
|||||||
const parent = view.parent as View;
|
const parent = view.parent as View;
|
||||||
|
|
||||||
let propertyNameToAnimate = animation.property;
|
let propertyNameToAnimate = animation.property;
|
||||||
|
let subPropertyNameToAnimate;
|
||||||
let toValue = animation.value;
|
let toValue = animation.value;
|
||||||
let fromValue;
|
let fromValue;
|
||||||
if (nativeView) {
|
if (nativeView) {
|
||||||
@ -334,6 +335,8 @@ export class Animation extends AnimationBase {
|
|||||||
};
|
};
|
||||||
fromValue = nativeView.layer.opacity;
|
fromValue = nativeView.layer.opacity;
|
||||||
break;
|
break;
|
||||||
|
// In the case of rotation, avoid animating affine transform directly as it will animate to the closest result
|
||||||
|
// that is visually the same. For example, 0 -> 360 will leave view as is.
|
||||||
case Properties.rotate:
|
case Properties.rotate:
|
||||||
animation._originalValue = {
|
animation._originalValue = {
|
||||||
x: view.rotateX,
|
x: view.rotateX,
|
||||||
@ -346,9 +349,30 @@ export class Animation extends AnimationBase {
|
|||||||
style[setLocal ? rotateYProperty.name : rotateYProperty.keyframe] = value.y;
|
style[setLocal ? rotateYProperty.name : rotateYProperty.keyframe] = value.y;
|
||||||
};
|
};
|
||||||
|
|
||||||
propertyNameToAnimate = 'transform';
|
propertyNameToAnimate = 'transform.rotation';
|
||||||
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
subPropertyNameToAnimate = ['x', 'y', 'z'];
|
||||||
toValue = NSValue.valueWithCATransform3D(iosHelper.applyRotateTransform(nativeView.layer.transform, toValue.x, toValue.y, toValue.z));
|
fromValue = {
|
||||||
|
x: nativeView.layer.valueForKeyPath('transform.rotation.x'),
|
||||||
|
y: nativeView.layer.valueForKeyPath('transform.rotation.y'),
|
||||||
|
z: nativeView.layer.valueForKeyPath('transform.rotation.z'),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (animation.target.rotateX !== undefined && animation.target.rotateX !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
||||||
|
fromValue.x = (animation.target.rotateX * Math.PI) / 180;
|
||||||
|
}
|
||||||
|
if (animation.target.rotateY !== undefined && animation.target.rotateY !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
||||||
|
fromValue.y = (animation.target.rotateY * Math.PI) / 180;
|
||||||
|
}
|
||||||
|
if (animation.target.rotate !== undefined && animation.target.rotate !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
||||||
|
fromValue.z = (animation.target.rotate * Math.PI) / 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Respect only value.z for back-compat until 3D rotations are implemented
|
||||||
|
toValue = {
|
||||||
|
x: (toValue.x * Math.PI) / 180,
|
||||||
|
y: (toValue.y * Math.PI) / 180,
|
||||||
|
z: (toValue.z * Math.PI) / 180,
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case Properties.translate:
|
case Properties.translate:
|
||||||
animation._originalValue = {
|
animation._originalValue = {
|
||||||
@ -365,10 +389,10 @@ export class Animation extends AnimationBase {
|
|||||||
break;
|
break;
|
||||||
case Properties.scale:
|
case Properties.scale:
|
||||||
if (toValue.x === 0) {
|
if (toValue.x === 0) {
|
||||||
toValue.x = 1e-6;
|
toValue.x = 0.001;
|
||||||
}
|
}
|
||||||
if (toValue.y === 0) {
|
if (toValue.y === 0) {
|
||||||
toValue.y = 1e-6;
|
toValue.y = 0.001;
|
||||||
}
|
}
|
||||||
animation._originalValue = { x: view.scaleX, y: view.scaleY };
|
animation._originalValue = { x: view.scaleX, y: view.scaleY };
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
@ -451,6 +475,7 @@ export class Animation extends AnimationBase {
|
|||||||
return {
|
return {
|
||||||
propertyNameToAnimate: propertyNameToAnimate,
|
propertyNameToAnimate: propertyNameToAnimate,
|
||||||
fromValue: fromValue,
|
fromValue: fromValue,
|
||||||
|
subPropertiesToAnimate: subPropertyNameToAnimate,
|
||||||
toValue: toValue,
|
toValue: toValue,
|
||||||
duration: duration,
|
duration: duration,
|
||||||
repeatCount: repeatCount,
|
repeatCount: repeatCount,
|
||||||
@ -496,10 +521,10 @@ export class Animation extends AnimationBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static _createGroupAnimation(args: AnimationInfo, animation: PropertyAnimation) {
|
private static _createGroupAnimation(args: AnimationInfo, animation: PropertyAnimation) {
|
||||||
const animations = NSMutableArray.alloc<CAAnimation>().initWithCapacity(args.subPropertiesToAnimate.length);
|
|
||||||
const groupAnimation = CAAnimationGroup.new();
|
const groupAnimation = CAAnimationGroup.new();
|
||||||
groupAnimation.duration = args.duration;
|
const animations = NSMutableArray.alloc<CAAnimation>().initWithCapacity(args.subPropertiesToAnimate.length);
|
||||||
|
|
||||||
|
groupAnimation.duration = args.duration;
|
||||||
if (args.repeatCount !== undefined) {
|
if (args.repeatCount !== undefined) {
|
||||||
groupAnimation.repeatCount = args.repeatCount;
|
groupAnimation.repeatCount = args.repeatCount;
|
||||||
}
|
}
|
||||||
@ -651,30 +676,16 @@ export class Animation extends AnimationBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value[Properties.scale] !== undefined) {
|
if (value[Properties.scale] !== undefined) {
|
||||||
const x = value[Properties.scale].x || 1e-6;
|
const x = value[Properties.scale].x;
|
||||||
const y = value[Properties.scale].y || 1e-6;
|
const y = value[Properties.scale].y;
|
||||||
result = CATransform3DScale(result, x, y, 1);
|
result = CATransform3DScale(result, x === 0 ? 0.001 : x, y === 0 ? 0.001 : y, 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (value[Properties.rotate] !== undefined) {
|
|
||||||
const x = value[Properties.rotate].x;
|
|
||||||
const y = value[Properties.rotate].y;
|
|
||||||
const z = value[Properties.rotate].z;
|
|
||||||
const perspective = animation.target.perspective || 300;
|
|
||||||
|
|
||||||
// Set perspective in case of rotation since we use z
|
|
||||||
if (x || y) {
|
|
||||||
result.m34 = -1 / perspective;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = iosHelper.applyRotateTransform(result, x, y, z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _isAffineTransform(property: string): boolean {
|
private static _isAffineTransform(property: string): boolean {
|
||||||
return property === _transform || property === Properties.translate || property === Properties.scale || property === Properties.rotate;
|
return property === _transform || property === Properties.translate || property === Properties.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _canBeMerged(animation1: PropertyAnimation, animation2: PropertyAnimation) {
|
private static _canBeMerged(animation1: PropertyAnimation, animation2: PropertyAnimation) {
|
||||||
@ -941,8 +952,7 @@ function calculateTransform(view: View): CATransform3D {
|
|||||||
// Order is important: translate, rotate, scale
|
// Order is important: translate, rotate, scale
|
||||||
let expectedTransform = new CATransform3D(CATransform3DIdentity);
|
let expectedTransform = new CATransform3D(CATransform3DIdentity);
|
||||||
|
|
||||||
// TODO: Add perspective property to transform animations (not just rotation)
|
// Only set perspective if there is 3D rotation
|
||||||
// Set perspective in case of rotation since we use z
|
|
||||||
if (view.rotateX || view.rotateY) {
|
if (view.rotateX || view.rotateY) {
|
||||||
expectedTransform.m34 = -1 / perspective;
|
expectedTransform.m34 = -1 / perspective;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user