mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
fix(animations): error handling
closes https://github.com/NativeScript/NativeScript/issues/10037
This commit is contained in:
@ -42,7 +42,8 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
|
|||||||
|
|
||||||
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean) {
|
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean) {
|
||||||
if (!animationDefinitions || animationDefinitions.length === 0) {
|
if (!animationDefinitions || animationDefinitions.length === 0) {
|
||||||
throw new Error('No animation definitions specified');
|
console.error('No animation definitions specified');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Trace.isEnabled()) {
|
if (Trace.isEnabled()) {
|
||||||
@ -58,7 +59,10 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._propertyAnimations.length === 0) {
|
if (this._propertyAnimations.length === 0) {
|
||||||
throw new Error('Nothing to animate.');
|
if (Trace.isEnabled()) {
|
||||||
|
Trace.write('Nothing to animate.', Trace.categories.Animation);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (Trace.isEnabled()) {
|
if (Trace.isEnabled()) {
|
||||||
Trace.write('Created ' + this._propertyAnimations.length + ' individual property animations.', Trace.categories.Animation);
|
Trace.write('Created ' + this._propertyAnimations.length + ' individual property animations.', Trace.categories.Animation);
|
||||||
@ -137,7 +141,8 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
|
|||||||
|
|
||||||
private static _createPropertyAnimations(animationDefinition: AnimationDefinition): Array<PropertyAnimation> {
|
private static _createPropertyAnimations(animationDefinition: AnimationDefinition): Array<PropertyAnimation> {
|
||||||
if (!animationDefinition.target) {
|
if (!animationDefinition.target) {
|
||||||
throw new Error('No animation target specified.');
|
console.error('No animation target specified.');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const item in animationDefinition) {
|
for (const item in animationDefinition) {
|
||||||
@ -147,18 +152,22 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((item === Properties.opacity || item === 'duration' || item === 'delay' || item === 'iterations') && typeof value !== 'number') {
|
if ((item === Properties.opacity || item === 'duration' || item === 'delay' || item === 'iterations') && typeof value !== 'number') {
|
||||||
throw new Error(`Property ${item} must be valid number. Value: ${value}`);
|
console.error(`Property ${item} must be valid number. Value: ${value}`);
|
||||||
|
return;
|
||||||
} else if ((item === Properties.scale || item === Properties.translate) && (typeof (<Pair>value).x !== 'number' || typeof (<Pair>value).y !== 'number')) {
|
} else if ((item === Properties.scale || item === Properties.translate) && (typeof (<Pair>value).x !== 'number' || typeof (<Pair>value).y !== 'number')) {
|
||||||
throw new Error(`Property ${item} must be valid Pair. Value: ${value}`);
|
console.error(`Property ${item} must be valid Pair. Value: ${value}`);
|
||||||
|
return;
|
||||||
} else if (item === Properties.backgroundColor && !Color.isValid(animationDefinition.backgroundColor)) {
|
} else if (item === Properties.backgroundColor && !Color.isValid(animationDefinition.backgroundColor)) {
|
||||||
throw new Error(`Property ${item} must be valid color. Value: ${value}`);
|
console.error(`Property ${item} must be valid color. Value: ${value}`);
|
||||||
|
return;
|
||||||
} else if (item === Properties.width || item === Properties.height) {
|
} else if (item === Properties.width || item === Properties.height) {
|
||||||
// Coerce input into a PercentLength object in case it's a string.
|
// Coerce input into a PercentLength object in case it's a string.
|
||||||
animationDefinition[item] = PercentLength.parse(<any>value);
|
animationDefinition[item] = PercentLength.parse(<any>value);
|
||||||
} else if (item === Properties.rotate) {
|
} else if (item === Properties.rotate) {
|
||||||
const rotate: number | Point3D = value;
|
const rotate: number | Point3D = value;
|
||||||
if (typeof rotate !== 'number' && !(typeof rotate.x === 'number' && typeof rotate.y === 'number' && typeof rotate.z === 'number')) {
|
if (typeof rotate !== 'number' && !(typeof rotate.x === 'number' && typeof rotate.y === 'number' && typeof rotate.z === 'number')) {
|
||||||
throw new Error(`Property ${rotate} must be valid number or Point3D. Value: ${value}`);
|
console.error(`Property ${rotate} must be valid number or Point3D. Value: ${value}`);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,7 +274,7 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (propertyAnimations.length === 0) {
|
if (propertyAnimations.length === 0) {
|
||||||
throw new Error('No known animation properties specified');
|
console.error('No known animation properties specified');
|
||||||
}
|
}
|
||||||
|
|
||||||
return propertyAnimations;
|
return propertyAnimations;
|
||||||
|
@ -136,7 +136,7 @@ export function _resolveAnimationCurve(curve: string | CubicBezierAnimationCurve
|
|||||||
|
|
||||||
return CAMediaTimingFunction.functionWithControlPoints(animationCurve.x1, animationCurve.y1, animationCurve.x2, animationCurve.y2);
|
return CAMediaTimingFunction.functionWithControlPoints(animationCurve.x1, animationCurve.y1, animationCurve.x2, animationCurve.y2);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Invalid animation curve: ${curve}`);
|
console.error(`Invalid animation curve: ${curve}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,140 +269,142 @@ export class Animation extends AnimationBase {
|
|||||||
let subPropertyNameToAnimate;
|
let subPropertyNameToAnimate;
|
||||||
let toValue = animation.value;
|
let toValue = animation.value;
|
||||||
let fromValue;
|
let fromValue;
|
||||||
const setLocal = valueSource === 'animation';
|
if (nativeView?.layer) {
|
||||||
|
const setLocal = valueSource === 'animation';
|
||||||
|
|
||||||
switch (animation.property) {
|
switch (animation.property) {
|
||||||
case Properties.backgroundColor:
|
case Properties.backgroundColor:
|
||||||
animation._originalValue = view.backgroundColor;
|
animation._originalValue = view.backgroundColor;
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
style[setLocal ? backgroundColorProperty.name : backgroundColorProperty.keyframe] = value;
|
style[setLocal ? backgroundColorProperty.name : backgroundColorProperty.keyframe] = value;
|
||||||
};
|
};
|
||||||
fromValue = nativeView.layer.backgroundColor;
|
fromValue = nativeView.layer.backgroundColor;
|
||||||
if (nativeView instanceof UILabel) {
|
if (nativeView instanceof UILabel) {
|
||||||
nativeView.setValueForKey(UIColor.clearColor, 'backgroundColor');
|
nativeView.setValueForKey(UIColor.clearColor, 'backgroundColor');
|
||||||
}
|
}
|
||||||
toValue = toValue.CGColor;
|
toValue = toValue.CGColor;
|
||||||
break;
|
break;
|
||||||
case Properties.opacity:
|
case Properties.opacity:
|
||||||
animation._originalValue = view.opacity;
|
animation._originalValue = view.opacity;
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
style[setLocal ? opacityProperty.name : opacityProperty.keyframe] = value;
|
style[setLocal ? opacityProperty.name : opacityProperty.keyframe] = value;
|
||||||
};
|
};
|
||||||
fromValue = nativeView.layer.opacity;
|
fromValue = nativeView.layer.opacity;
|
||||||
break;
|
break;
|
||||||
case Properties.rotate:
|
case Properties.rotate:
|
||||||
animation._originalValue = {
|
animation._originalValue = {
|
||||||
x: view.rotateX,
|
x: view.rotateX,
|
||||||
y: view.rotateY,
|
y: view.rotateY,
|
||||||
z: view.rotate,
|
z: view.rotate,
|
||||||
};
|
};
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
style[setLocal ? rotateProperty.name : rotateProperty.keyframe] = value.z;
|
style[setLocal ? rotateProperty.name : rotateProperty.keyframe] = value.z;
|
||||||
style[setLocal ? rotateXProperty.name : rotateXProperty.keyframe] = value.x;
|
style[setLocal ? rotateXProperty.name : rotateXProperty.keyframe] = value.x;
|
||||||
style[setLocal ? rotateYProperty.name : rotateYProperty.keyframe] = value.y;
|
style[setLocal ? rotateYProperty.name : rotateYProperty.keyframe] = value.y;
|
||||||
};
|
};
|
||||||
|
|
||||||
propertyNameToAnimate = 'transform.rotation';
|
propertyNameToAnimate = 'transform.rotation';
|
||||||
subPropertyNameToAnimate = ['x', 'y', 'z'];
|
subPropertyNameToAnimate = ['x', 'y', 'z'];
|
||||||
fromValue = {
|
fromValue = {
|
||||||
x: nativeView.layer.valueForKeyPath('transform.rotation.x'),
|
x: nativeView.layer.valueForKeyPath('transform.rotation.x'),
|
||||||
y: nativeView.layer.valueForKeyPath('transform.rotation.y'),
|
y: nativeView.layer.valueForKeyPath('transform.rotation.y'),
|
||||||
z: nativeView.layer.valueForKeyPath('transform.rotation.z'),
|
z: nativeView.layer.valueForKeyPath('transform.rotation.z'),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (animation.target.rotateX !== undefined && animation.target.rotateX !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
if (animation.target.rotateX !== undefined && animation.target.rotateX !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
||||||
fromValue.x = (animation.target.rotateX * Math.PI) / 180;
|
fromValue.x = (animation.target.rotateX * Math.PI) / 180;
|
||||||
}
|
}
|
||||||
if (animation.target.rotateY !== undefined && animation.target.rotateY !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
if (animation.target.rotateY !== undefined && animation.target.rotateY !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
||||||
fromValue.y = (animation.target.rotateY * Math.PI) / 180;
|
fromValue.y = (animation.target.rotateY * Math.PI) / 180;
|
||||||
}
|
}
|
||||||
if (animation.target.rotate !== undefined && animation.target.rotate !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
if (animation.target.rotate !== undefined && animation.target.rotate !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
|
||||||
fromValue.z = (animation.target.rotate * Math.PI) / 180;
|
fromValue.z = (animation.target.rotate * Math.PI) / 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respect only value.z for back-compat until 3D rotations are implemented
|
// Respect only value.z for back-compat until 3D rotations are implemented
|
||||||
toValue = {
|
toValue = {
|
||||||
x: (toValue.x * Math.PI) / 180,
|
x: (toValue.x * Math.PI) / 180,
|
||||||
y: (toValue.y * Math.PI) / 180,
|
y: (toValue.y * Math.PI) / 180,
|
||||||
z: (toValue.z * Math.PI) / 180,
|
z: (toValue.z * Math.PI) / 180,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case Properties.translate:
|
case Properties.translate:
|
||||||
animation._originalValue = {
|
animation._originalValue = {
|
||||||
x: view.translateX,
|
x: view.translateX,
|
||||||
y: view.translateY,
|
y: view.translateY,
|
||||||
};
|
};
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value.x;
|
style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value.x;
|
||||||
style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value.y;
|
style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value.y;
|
||||||
};
|
};
|
||||||
propertyNameToAnimate = 'transform';
|
propertyNameToAnimate = 'transform';
|
||||||
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
||||||
toValue = NSValue.valueWithCATransform3D(CATransform3DTranslate(nativeView.layer.transform, toValue.x, toValue.y, 0));
|
toValue = NSValue.valueWithCATransform3D(CATransform3DTranslate(nativeView.layer.transform, toValue.x, toValue.y, 0));
|
||||||
break;
|
break;
|
||||||
case Properties.scale:
|
case Properties.scale:
|
||||||
if (toValue.x === 0) {
|
if (toValue.x === 0) {
|
||||||
toValue.x = 0.001;
|
toValue.x = 0.001;
|
||||||
|
}
|
||||||
|
if (toValue.y === 0) {
|
||||||
|
toValue.y = 0.001;
|
||||||
|
}
|
||||||
|
animation._originalValue = { x: view.scaleX, y: view.scaleY };
|
||||||
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
|
style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x;
|
||||||
|
style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y;
|
||||||
|
};
|
||||||
|
propertyNameToAnimate = 'transform';
|
||||||
|
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
||||||
|
toValue = NSValue.valueWithCATransform3D(CATransform3DScale(nativeView.layer.transform, toValue.x, toValue.y, 1));
|
||||||
|
break;
|
||||||
|
case _transform:
|
||||||
|
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
||||||
|
animation._originalValue = {
|
||||||
|
xs: view.scaleX,
|
||||||
|
ys: view.scaleY,
|
||||||
|
xt: view.translateX,
|
||||||
|
yt: view.translateY,
|
||||||
|
rx: view.rotateX,
|
||||||
|
ry: view.rotateY,
|
||||||
|
rz: view.rotate,
|
||||||
|
};
|
||||||
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
|
style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value.xt;
|
||||||
|
style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value.yt;
|
||||||
|
style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.xs;
|
||||||
|
style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.ys;
|
||||||
|
style[setLocal ? rotateXProperty.name : rotateXProperty.keyframe] = value.rx;
|
||||||
|
style[setLocal ? rotateYProperty.name : rotateYProperty.keyframe] = value.ry;
|
||||||
|
style[setLocal ? rotateProperty.name : rotateProperty.keyframe] = value.rz;
|
||||||
|
};
|
||||||
|
propertyNameToAnimate = 'transform';
|
||||||
|
toValue = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation));
|
||||||
|
break;
|
||||||
|
case Properties.width:
|
||||||
|
case Properties.height: {
|
||||||
|
const direction: string = animation.property;
|
||||||
|
const isHeight: boolean = direction === 'height';
|
||||||
|
propertyNameToAnimate = 'bounds';
|
||||||
|
if (!parent) {
|
||||||
|
console.error(`cannot animate ${direction} on root view`);
|
||||||
|
}
|
||||||
|
const parentExtent: number = isHeight ? parent.getMeasuredHeight() : parent.getMeasuredWidth();
|
||||||
|
const asNumber = PercentLength.toDevicePixels(PercentLength.parse(toValue), parentExtent, parentExtent) / Screen.mainScreen.scale;
|
||||||
|
const currentBounds = nativeView.layer.bounds;
|
||||||
|
const extentX = isHeight ? currentBounds.size.width : asNumber;
|
||||||
|
const extentY = isHeight ? asNumber : currentBounds.size.height;
|
||||||
|
fromValue = NSValue.valueWithCGRect(currentBounds);
|
||||||
|
toValue = NSValue.valueWithCGRect(CGRectMake(currentBounds.origin.x, currentBounds.origin.y, extentX, extentY));
|
||||||
|
animation._originalValue = view.height;
|
||||||
|
animation._propertyResetCallback = (value, valueSource) => {
|
||||||
|
const prop = isHeight ? heightProperty : widthProperty;
|
||||||
|
style[setLocal ? prop.name : prop.keyframe] = value;
|
||||||
|
};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (toValue.y === 0) {
|
default:
|
||||||
toValue.y = 0.001;
|
console.error(`Animating property '${animation.property}' is unsupported`);
|
||||||
}
|
|
||||||
animation._originalValue = { x: view.scaleX, y: view.scaleY };
|
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
|
||||||
style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x;
|
|
||||||
style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y;
|
|
||||||
};
|
|
||||||
propertyNameToAnimate = 'transform';
|
|
||||||
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
|
||||||
toValue = NSValue.valueWithCATransform3D(CATransform3DScale(nativeView.layer.transform, toValue.x, toValue.y, 1));
|
|
||||||
break;
|
|
||||||
case _transform:
|
|
||||||
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
|
|
||||||
animation._originalValue = {
|
|
||||||
xs: view.scaleX,
|
|
||||||
ys: view.scaleY,
|
|
||||||
xt: view.translateX,
|
|
||||||
yt: view.translateY,
|
|
||||||
rx: view.rotateX,
|
|
||||||
ry: view.rotateY,
|
|
||||||
rz: view.rotate,
|
|
||||||
};
|
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
|
||||||
style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value.xt;
|
|
||||||
style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value.yt;
|
|
||||||
style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.xs;
|
|
||||||
style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.ys;
|
|
||||||
style[setLocal ? rotateXProperty.name : rotateXProperty.keyframe] = value.rx;
|
|
||||||
style[setLocal ? rotateYProperty.name : rotateYProperty.keyframe] = value.ry;
|
|
||||||
style[setLocal ? rotateProperty.name : rotateProperty.keyframe] = value.rz;
|
|
||||||
};
|
|
||||||
propertyNameToAnimate = 'transform';
|
|
||||||
toValue = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation));
|
|
||||||
break;
|
|
||||||
case Properties.width:
|
|
||||||
case Properties.height: {
|
|
||||||
const direction: string = animation.property;
|
|
||||||
const isHeight: boolean = direction === 'height';
|
|
||||||
propertyNameToAnimate = 'bounds';
|
|
||||||
if (!parent) {
|
|
||||||
throw new Error(`cannot animate ${direction} on root view`);
|
|
||||||
}
|
|
||||||
const parentExtent: number = isHeight ? parent.getMeasuredHeight() : parent.getMeasuredWidth();
|
|
||||||
const asNumber = PercentLength.toDevicePixels(PercentLength.parse(toValue), parentExtent, parentExtent) / Screen.mainScreen.scale;
|
|
||||||
const currentBounds = nativeView.layer.bounds;
|
|
||||||
const extentX = isHeight ? currentBounds.size.width : asNumber;
|
|
||||||
const extentY = isHeight ? asNumber : currentBounds.size.height;
|
|
||||||
fromValue = NSValue.valueWithCGRect(currentBounds);
|
|
||||||
toValue = NSValue.valueWithCGRect(CGRectMake(currentBounds.origin.x, currentBounds.origin.y, extentX, extentY));
|
|
||||||
animation._originalValue = view.height;
|
|
||||||
animation._propertyResetCallback = (value, valueSource) => {
|
|
||||||
const prop = isHeight ? heightProperty : widthProperty;
|
|
||||||
style[setLocal ? prop.name : prop.keyframe] = value;
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
throw new Error(`Animating property '${animation.property}' is unsupported`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let duration = 0.3;
|
let duration = 0.3;
|
||||||
@ -437,26 +439,28 @@ export class Animation extends AnimationBase {
|
|||||||
|
|
||||||
private static _createNativeAnimation(propertyAnimations: Array<PropertyAnimation>, index: number, playSequentially: boolean, args: AnimationInfo, animation: PropertyAnimation, valueSource: 'animation' | 'keyframe', finishedCallback: (cancelled?: boolean) => void) {
|
private static _createNativeAnimation(propertyAnimations: Array<PropertyAnimation>, index: number, playSequentially: boolean, args: AnimationInfo, animation: PropertyAnimation, valueSource: 'animation' | 'keyframe', finishedCallback: (cancelled?: boolean) => void) {
|
||||||
const nativeView = <UIView>animation.target.nativeViewProtected;
|
const nativeView = <UIView>animation.target.nativeViewProtected;
|
||||||
let nativeAnimation;
|
if (nativeView?.layer) {
|
||||||
|
let nativeAnimation;
|
||||||
|
|
||||||
if (args.subPropertiesToAnimate) {
|
if (args.subPropertiesToAnimate) {
|
||||||
nativeAnimation = this._createGroupAnimation(args, animation);
|
nativeAnimation = this._createGroupAnimation(args, animation);
|
||||||
} else {
|
|
||||||
nativeAnimation = this._createBasicAnimation(args, animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
const animationDelegate = AnimationDelegateImpl.initWithFinishedCallback(finishedCallback, animation, valueSource);
|
|
||||||
nativeAnimation.setValueForKey(animationDelegate, 'delegate');
|
|
||||||
|
|
||||||
nativeView.layer.addAnimationForKey(nativeAnimation, args.propertyNameToAnimate);
|
|
||||||
|
|
||||||
let callback = undefined;
|
|
||||||
if (index + 1 < propertyAnimations.length) {
|
|
||||||
callback = Animation._createiOSAnimationFunction(propertyAnimations, index + 1, playSequentially, valueSource, finishedCallback);
|
|
||||||
if (!playSequentially) {
|
|
||||||
callback();
|
|
||||||
} else {
|
} else {
|
||||||
animationDelegate.nextAnimation = callback;
|
nativeAnimation = this._createBasicAnimation(args, animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
const animationDelegate = AnimationDelegateImpl.initWithFinishedCallback(finishedCallback, animation, valueSource);
|
||||||
|
nativeAnimation.setValueForKey(animationDelegate, 'delegate');
|
||||||
|
|
||||||
|
nativeView.layer.addAnimationForKey(nativeAnimation, args.propertyNameToAnimate);
|
||||||
|
|
||||||
|
let callback = undefined;
|
||||||
|
if (index + 1 < propertyAnimations.length) {
|
||||||
|
callback = Animation._createiOSAnimationFunction(propertyAnimations, index + 1, playSequentially, valueSource, finishedCallback);
|
||||||
|
if (!playSequentially) {
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
animationDelegate.nextAnimation = callback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user