fix(animations): error handling

closes https://github.com/NativeScript/NativeScript/issues/10037
This commit is contained in:
Nathan Walker
2022-09-23 10:27:01 -07:00
parent 1c82d19455
commit 36ad24c037
2 changed files with 168 additions and 155 deletions

View File

@ -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;

View File

@ -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,6 +269,7 @@ export class Animation extends AnimationBase {
let subPropertyNameToAnimate; let subPropertyNameToAnimate;
let toValue = animation.value; let toValue = animation.value;
let fromValue; let fromValue;
if (nativeView?.layer) {
const setLocal = valueSource === 'animation'; const setLocal = valueSource === 'animation';
switch (animation.property) { switch (animation.property) {
@ -385,7 +386,7 @@ export class Animation extends AnimationBase {
const isHeight: boolean = direction === 'height'; const isHeight: boolean = direction === 'height';
propertyNameToAnimate = 'bounds'; propertyNameToAnimate = 'bounds';
if (!parent) { if (!parent) {
throw new Error(`cannot animate ${direction} on root view`); console.error(`cannot animate ${direction} on root view`);
} }
const parentExtent: number = isHeight ? parent.getMeasuredHeight() : parent.getMeasuredWidth(); const parentExtent: number = isHeight ? parent.getMeasuredHeight() : parent.getMeasuredWidth();
const asNumber = PercentLength.toDevicePixels(PercentLength.parse(toValue), parentExtent, parentExtent) / Screen.mainScreen.scale; const asNumber = PercentLength.toDevicePixels(PercentLength.parse(toValue), parentExtent, parentExtent) / Screen.mainScreen.scale;
@ -402,7 +403,8 @@ export class Animation extends AnimationBase {
break; break;
} }
default: default:
throw new Error(`Animating property '${animation.property}' is unsupported`); console.error(`Animating property '${animation.property}' is unsupported`);
}
} }
let duration = 0.3; let duration = 0.3;
@ -437,6 +439,7 @@ 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;
if (nativeView?.layer) {
let nativeAnimation; let nativeAnimation;
if (args.subPropertiesToAnimate) { if (args.subPropertiesToAnimate) {
@ -460,6 +463,7 @@ export class Animation extends AnimationBase {
} }
} }
} }
}
private static _createGroupAnimation(args: AnimationInfo, animation: PropertyAnimation) { private static _createGroupAnimation(args: AnimationInfo, animation: PropertyAnimation) {
const groupAnimation = CAAnimationGroup.new(); const groupAnimation = CAAnimationGroup.new();