chore: default tabs

This commit is contained in:
Nathan Walker
2020-07-09 23:46:02 -07:00
parent 8100cf7089
commit 41f0573d8e
353 changed files with 55344 additions and 55344 deletions

View File

@@ -10,274 +10,274 @@ import { PercentLength } from '../styling/style-properties';
export * from './animation-interfaces';
export module Properties {
export const opacity = 'opacity';
export const backgroundColor = 'backgroundColor';
export const translate = 'translate';
export const rotate = 'rotate';
export const scale = 'scale';
export const height = 'height';
export const width = 'width';
export const opacity = 'opacity';
export const backgroundColor = 'backgroundColor';
export const translate = 'translate';
export const rotate = 'rotate';
export const scale = 'scale';
export const height = 'height';
export const width = 'width';
}
export class CubicBezierAnimationCurve implements CubicBezierAnimationCurveDefinition {
public x1: number;
public y1: number;
public x2: number;
public y2: number;
public x1: number;
public y1: number;
public x2: number;
public y2: number;
constructor(x1: number, y1: number, x2: number, y2: number) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
constructor(x1: number, y1: number, x2: number, y2: number) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
}
export abstract class AnimationBase implements AnimationBaseDefinition {
public _propertyAnimations: Array<PropertyAnimation>;
public _playSequentially: boolean;
private _isPlaying: boolean;
private _resolve;
private _reject;
public _propertyAnimations: Array<PropertyAnimation>;
public _playSequentially: boolean;
private _isPlaying: boolean;
private _resolve;
private _reject;
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean) {
if (!animationDefinitions || animationDefinitions.length === 0) {
throw new Error('No animation definitions specified');
}
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean) {
if (!animationDefinitions || animationDefinitions.length === 0) {
throw new Error('No animation definitions specified');
}
if (Trace.isEnabled()) {
Trace.write('Analyzing ' + animationDefinitions.length + ' animation definitions...', Trace.categories.Animation);
}
if (Trace.isEnabled()) {
Trace.write('Analyzing ' + animationDefinitions.length + ' animation definitions...', Trace.categories.Animation);
}
this._propertyAnimations = new Array<PropertyAnimation>();
for (let i = 0, length = animationDefinitions.length; i < length; i++) {
if (animationDefinitions[i].curve) {
animationDefinitions[i].curve = this._resolveAnimationCurve(animationDefinitions[i].curve);
}
this._propertyAnimations = this._propertyAnimations.concat(AnimationBase._createPropertyAnimations(animationDefinitions[i]));
}
this._propertyAnimations = new Array<PropertyAnimation>();
for (let i = 0, length = animationDefinitions.length; i < length; i++) {
if (animationDefinitions[i].curve) {
animationDefinitions[i].curve = this._resolveAnimationCurve(animationDefinitions[i].curve);
}
this._propertyAnimations = this._propertyAnimations.concat(AnimationBase._createPropertyAnimations(animationDefinitions[i]));
}
if (this._propertyAnimations.length === 0) {
throw new Error('Nothing to animate.');
}
if (Trace.isEnabled()) {
Trace.write('Created ' + this._propertyAnimations.length + ' individual property animations.', Trace.categories.Animation);
}
if (this._propertyAnimations.length === 0) {
throw new Error('Nothing to animate.');
}
if (Trace.isEnabled()) {
Trace.write('Created ' + this._propertyAnimations.length + ' individual property animations.', Trace.categories.Animation);
}
this._playSequentially = playSequentially;
}
this._playSequentially = playSequentially;
}
abstract _resolveAnimationCurve(curve: any): any;
abstract _resolveAnimationCurve(curve: any): any;
protected _rejectAlreadyPlaying(): AnimationPromiseDefinition {
const reason = 'Animation is already playing.';
Trace.write(reason, Trace.categories.Animation, Trace.messageType.warn);
protected _rejectAlreadyPlaying(): AnimationPromiseDefinition {
const reason = 'Animation is already playing.';
Trace.write(reason, Trace.categories.Animation, Trace.messageType.warn);
return <AnimationPromiseDefinition>new Promise<void>((resolve, reject) => {
reject(reason);
});
}
return <AnimationPromiseDefinition>new Promise<void>((resolve, reject) => {
reject(reason);
});
}
public play(): AnimationPromiseDefinition {
// We have to actually create a "Promise" due to a bug in the v8 engine and decedent promises
// We just cast it to a animationPromise so that all the rest of the code works fine
const animationFinishedPromise = <AnimationPromiseDefinition>new Promise<void>((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
public play(): AnimationPromiseDefinition {
// We have to actually create a "Promise" due to a bug in the v8 engine and decedent promises
// We just cast it to a animationPromise so that all the rest of the code works fine
const animationFinishedPromise = <AnimationPromiseDefinition>new Promise<void>((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
this.fixupAnimationPromise(animationFinishedPromise);
this.fixupAnimationPromise(animationFinishedPromise);
this._isPlaying = true;
this._isPlaying = true;
return animationFinishedPromise;
}
return animationFinishedPromise;
}
private fixupAnimationPromise(promise: AnimationPromiseDefinition): void {
// Since we are using function() below because of arguments, TS won't automatically do a _this for those functions.
const _this = this;
promise.cancel = () => {
_this.cancel();
};
const _then = promise.then;
promise.then = function () {
const r = _then.apply(promise, arguments);
_this.fixupAnimationPromise(r);
private fixupAnimationPromise(promise: AnimationPromiseDefinition): void {
// Since we are using function() below because of arguments, TS won't automatically do a _this for those functions.
const _this = this;
promise.cancel = () => {
_this.cancel();
};
const _then = promise.then;
promise.then = function () {
const r = _then.apply(promise, arguments);
_this.fixupAnimationPromise(r);
return r;
};
const _catch = promise.catch;
promise.catch = function () {
const r = _catch.apply(promise, arguments);
_this.fixupAnimationPromise(r);
return r;
};
const _catch = promise.catch;
promise.catch = function () {
const r = _catch.apply(promise, arguments);
_this.fixupAnimationPromise(r);
return r;
};
}
return r;
};
}
public cancel(): void {
// Implemented in platform specific files
}
public cancel(): void {
// Implemented in platform specific files
}
public get isPlaying(): boolean {
return this._isPlaying;
}
public get isPlaying(): boolean {
return this._isPlaying;
}
public _resolveAnimationFinishedPromise() {
this._isPlaying = false;
this._resolve();
}
public _resolveAnimationFinishedPromise() {
this._isPlaying = false;
this._resolve();
}
public _rejectAnimationFinishedPromise() {
this._isPlaying = false;
this._reject(new Error('Animation cancelled.'));
}
public _rejectAnimationFinishedPromise() {
this._isPlaying = false;
this._reject(new Error('Animation cancelled.'));
}
private static _createPropertyAnimations(animationDefinition: AnimationDefinition): Array<PropertyAnimation> {
if (!animationDefinition.target) {
throw new Error('No animation target specified.');
}
private static _createPropertyAnimations(animationDefinition: AnimationDefinition): Array<PropertyAnimation> {
if (!animationDefinition.target) {
throw new Error('No animation target specified.');
}
for (let item in animationDefinition) {
const value = animationDefinition[item];
if (value === undefined) {
continue;
}
for (let item in animationDefinition) {
const value = animationDefinition[item];
if (value === undefined) {
continue;
}
if ((item === Properties.opacity || item === 'duration' || item === 'delay' || item === 'iterations') && typeof value !== 'number') {
throw new Error(`Property ${item} must be valid number. Value: ${value}`);
} 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}`);
} else if (item === Properties.backgroundColor && !Color.isValid(animationDefinition.backgroundColor)) {
throw new Error(`Property ${item} must be valid color. Value: ${value}`);
} else if (item === Properties.width || item === Properties.height) {
// Coerce input into a PercentLength object in case it's a string.
animationDefinition[item] = PercentLength.parse(<any>value);
} else if (item === Properties.rotate) {
const rotate: number | Point3D = value;
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}`);
}
}
}
if ((item === Properties.opacity || item === 'duration' || item === 'delay' || item === 'iterations') && typeof value !== 'number') {
throw new Error(`Property ${item} must be valid number. Value: ${value}`);
} 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}`);
} else if (item === Properties.backgroundColor && !Color.isValid(animationDefinition.backgroundColor)) {
throw new Error(`Property ${item} must be valid color. Value: ${value}`);
} else if (item === Properties.width || item === Properties.height) {
// Coerce input into a PercentLength object in case it's a string.
animationDefinition[item] = PercentLength.parse(<any>value);
} else if (item === Properties.rotate) {
const rotate: number | Point3D = value;
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}`);
}
}
}
const propertyAnimations = new Array<PropertyAnimation>();
const propertyAnimations = new Array<PropertyAnimation>();
// opacity
if (animationDefinition.opacity !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.opacity,
value: animationDefinition.opacity,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// opacity
if (animationDefinition.opacity !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.opacity,
value: animationDefinition.opacity,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// backgroundColor
if (animationDefinition.backgroundColor !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.backgroundColor,
value: typeof animationDefinition.backgroundColor === 'string' ? new Color(<any>animationDefinition.backgroundColor) : animationDefinition.backgroundColor,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// backgroundColor
if (animationDefinition.backgroundColor !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.backgroundColor,
value: typeof animationDefinition.backgroundColor === 'string' ? new Color(<any>animationDefinition.backgroundColor) : animationDefinition.backgroundColor,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// translate
if (animationDefinition.translate !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.translate,
value: animationDefinition.translate,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// translate
if (animationDefinition.translate !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.translate,
value: animationDefinition.translate,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// scale
if (animationDefinition.scale !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.scale,
value: animationDefinition.scale,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// scale
if (animationDefinition.scale !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.scale,
value: animationDefinition.scale,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// rotate
if (animationDefinition.rotate !== undefined) {
// Make sure the value of the rotation property is always Point3D
let rotationValue: Point3D;
if (typeof animationDefinition.rotate === 'number') {
rotationValue = { x: 0, y: 0, z: animationDefinition.rotate };
} else {
rotationValue = animationDefinition.rotate;
}
// rotate
if (animationDefinition.rotate !== undefined) {
// Make sure the value of the rotation property is always Point3D
let rotationValue: Point3D;
if (typeof animationDefinition.rotate === 'number') {
rotationValue = { x: 0, y: 0, z: animationDefinition.rotate };
} else {
rotationValue = animationDefinition.rotate;
}
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.rotate,
value: rotationValue,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.rotate,
value: rotationValue,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// height
if (animationDefinition.height !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.height,
value: animationDefinition.height,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// height
if (animationDefinition.height !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.height,
value: animationDefinition.height,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// width
if (animationDefinition.width !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.width,
value: animationDefinition.width,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
// width
if (animationDefinition.width !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.width,
value: animationDefinition.width,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve,
});
}
if (propertyAnimations.length === 0) {
throw new Error('No known animation properties specified');
}
if (propertyAnimations.length === 0) {
throw new Error('No known animation properties specified');
}
return propertyAnimations;
}
return propertyAnimations;
}
public static _getAnimationInfo(animation: PropertyAnimation): string {
return JSON.stringify({
target: animation.target.id,
property: animation.property,
value: animation.value,
duration: animation.duration,
delay: animation.delay,
iterations: animation.iterations,
curve: animation.curve,
});
}
public static _getAnimationInfo(animation: PropertyAnimation): string {
return JSON.stringify({
target: animation.target.id,
property: animation.property,
value: animation.value,
duration: animation.duration,
delay: animation.delay,
iterations: animation.iterations,
curve: animation.curve,
});
}
}

View File

@@ -4,8 +4,8 @@ import { PercentLength } from '../styling/style-properties';
import { Color } from '../../color';
export type Transformation = {
property: TransformationType;
value: TransformationValue;
property: TransformationType;
value: TransformationValue;
};
export type TransformationType = 'rotate' | 'translate' | 'translateX' | 'translateY' | 'scale' | 'scaleX' | 'scaleY';
@@ -13,58 +13,58 @@ export type TransformationType = 'rotate' | 'translate' | 'translateX' | 'transl
export type TransformationValue = Pair | number;
export type TransformFunctionsInfo = {
translate: Pair;
rotate: number;
scale: Pair;
translate: Pair;
rotate: number;
scale: Pair;
};
export type AnimationPromise = Promise<void> & Cancelable;
export interface Pair {
x: number;
y: number;
x: number;
y: number;
}
export interface Cancelable {
cancel(): void;
cancel(): void;
}
export interface PropertyAnimation {
target: View;
property: string;
value: any;
duration?: number;
delay?: number;
iterations?: number;
curve?: any;
target: View;
property: string;
value: any;
duration?: number;
delay?: number;
iterations?: number;
curve?: any;
}
export interface PropertyAnimationInfo extends PropertyAnimation {
_propertyResetCallback?: any;
_originalValue?: any;
_propertyResetCallback?: any;
_originalValue?: any;
}
export interface AnimationDefinition {
target?: View;
opacity?: number;
backgroundColor?: Color;
translate?: Pair;
scale?: Pair;
height?: PercentLength | string;
width?: PercentLength | string;
rotate?: number;
duration?: number;
delay?: number;
iterations?: number;
curve?: any;
target?: View;
opacity?: number;
backgroundColor?: Color;
translate?: Pair;
scale?: Pair;
height?: PercentLength | string;
width?: PercentLength | string;
rotate?: number;
duration?: number;
delay?: number;
iterations?: number;
curve?: any;
}
export interface AnimationDefinitionInternal extends AnimationDefinition {
valueSource?: 'animation' | 'keyframe';
valueSource?: 'animation' | 'keyframe';
}
export interface IOSView extends View {
_suspendPresentationLayerUpdates();
_resumePresentationLayerUpdates();
_isPresentationLayerUpdateSuspeneded();
_suspendPresentationLayerUpdates();
_resumePresentationLayerUpdates();
_isPresentationLayerUpdateSuspeneded();
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -8,68 +8,68 @@ export { KeyframeAnimation, KeyframeAnimationInfo, KeyframeDeclaration, Keyframe
* Defines animation options for the View.animate method.
*/
export interface AnimationDefinition {
/**
* The view whose property is to be animated.
*/
target?: View;
/**
* The view whose property is to be animated.
*/
target?: View;
/**
* Animates the opacity of the view. Value should be a number between 0.0 and 1.0
*/
opacity?: number;
/**
* Animates the opacity of the view. Value should be a number between 0.0 and 1.0
*/
opacity?: number;
/**
* Animates the backgroundColor of the view.
*/
backgroundColor?: Color;
/**
* Animates the backgroundColor of the view.
*/
backgroundColor?: Color;
/**
* Animates the translate affine transform of the view.
*/
translate?: Pair;
/**
* Animates the translate affine transform of the view.
*/
translate?: Pair;
/**
* Animates the scale affine transform of the view.
*/
scale?: Pair;
/**
* Animates the scale affine transform of the view.
*/
scale?: Pair;
/**
* Animates the height of a view.
*/
height?: PercentLength | string;
/**
* Animates the height of a view.
*/
height?: PercentLength | string;
/**
* Animates the width of a view.
*/
width?: PercentLength | string;
/**
* Animates the width of a view.
*/
width?: PercentLength | string;
/**
* Animates the rotate affine transform of the view. Value should be a number specifying the rotation amount in degrees.
*/
rotate?: number | Point3D;
/**
* Animates the rotate affine transform of the view. Value should be a number specifying the rotation amount in degrees.
*/
rotate?: number | Point3D;
/**
* The length of the animation in milliseconds. The default duration is 300 milliseconds.
*/
duration?: number;
/**
* The length of the animation in milliseconds. The default duration is 300 milliseconds.
*/
duration?: number;
/**
* The amount of time, in milliseconds, to delay starting the animation.
*/
delay?: number;
/**
* The amount of time, in milliseconds, to delay starting the animation.
*/
delay?: number;
/**
* Specifies how many times the animation should be played. Default is 1.
* iOS animations support fractional iterations, i.e. 1.5.
* To repeat an animation infinitely, use Number.POSITIVE_INFINITY
*/
iterations?: number;
/**
* Specifies how many times the animation should be played. Default is 1.
* iOS animations support fractional iterations, i.e. 1.5.
* To repeat an animation infinitely, use Number.POSITIVE_INFINITY
*/
iterations?: number;
/**
* An optional animation curve. Possible values are contained in the [AnimationCurve enumeration](../modules/_ui_enums_.animationcurve.html).
* Alternatively, you can pass an instance of type UIViewAnimationCurve for iOS or android.animation.TimeInterpolator for Android.
*/
curve?: any;
/**
* An optional animation curve. Possible values are contained in the [AnimationCurve enumeration](../modules/_ui_enums_.animationcurve.html).
* Alternatively, you can pass an instance of type UIViewAnimationCurve for iOS or android.animation.TimeInterpolator for Android.
*/
curve?: any;
}
/**
@@ -77,20 +77,20 @@ export interface AnimationDefinition {
* Possible values are numeric values from 0 to 1
*/
export class CubicBezierAnimationCurve {
public x1: number;
public y1: number;
public x2: number;
public y2: number;
public x1: number;
public y1: number;
public x2: number;
public y2: number;
constructor(x1: number, y1: number, x2: number, y2: number);
constructor(x1: number, y1: number, x2: number, y2: number);
}
/**
* Defines a key-value pair for css transformation
*/
export type Transformation = {
property: TransformationType;
value: TransformationValue;
property: TransformationType;
value: TransformationValue;
};
/**
@@ -107,30 +107,30 @@ export type TransformationValue = Point3D | Pair | number;
* Defines a point in 3d space (x, y and z) for rotation in 3d animations.
*/
export interface Point3D {
x: number;
y: number;
z: number;
x: number;
y: number;
z: number;
}
/**
* Defines a pair of values (horizontal and vertical) for translate and scale animations.
*/
export interface Pair {
x: number;
y: number;
x: number;
y: number;
}
/**
* Defines full information for css transformation
*/
export type TransformFunctionsInfo = {
translate: Pair;
rotate: Point3D;
scale: Pair;
translate: Pair;
rotate: Point3D;
scale: Pair;
};
export interface Cancelable {
cancel(): void;
cancel(): void;
}
/**
@@ -142,11 +142,11 @@ export type AnimationPromise = Promise<void> & Cancelable;
* Defines a animation set.
*/
export class Animation {
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
public play: (resetOnFinish?: boolean) => AnimationPromise;
public cancel: () => void;
public isPlaying: boolean;
public _resolveAnimationCurve(curve: any): any;
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
public play: (resetOnFinish?: boolean) => AnimationPromise;
public cancel: () => void;
public isPlaying: boolean;
public _resolveAnimationCurve(curve: any): any;
}
export function _resolveAnimationCurve(curve: any): any;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -3,104 +3,104 @@ import { View } from '../core/view';
export declare const ANIMATION_PROPERTIES;
export interface Keyframes {
name: string;
keyframes: Array<UnparsedKeyframe>;
name: string;
keyframes: Array<UnparsedKeyframe>;
}
export interface UnparsedKeyframe {
values: Array<any>;
declarations: Array<KeyframeDeclaration>;
values: Array<any>;
declarations: Array<KeyframeDeclaration>;
}
export interface KeyframeDeclaration {
property: string;
value: any;
property: string;
value: any;
}
export interface KeyframeInfo {
duration: number;
declarations: Array<KeyframeDeclaration>;
curve?: any;
duration: number;
declarations: Array<KeyframeDeclaration>;
curve?: any;
}
/**
* Defines animation options for the View.animate method.
*/
export class KeyframeAnimationInfo {
/**
* Return animation keyframes.
*/
keyframes: Array<KeyframeInfo>;
/**
* Return animation keyframes.
*/
keyframes: Array<KeyframeInfo>;
/**
* The animation name.
*/
name?: string;
/**
* The animation name.
*/
name?: string;
/**
* The length of the animation in milliseconds. The default duration is 300 milliseconds.
*/
duration?: number;
/**
* The length of the animation in milliseconds. The default duration is 300 milliseconds.
*/
duration?: number;
/**
* The amount of time, in milliseconds, to delay starting the animation.
*/
delay?: number;
/**
* The amount of time, in milliseconds, to delay starting the animation.
*/
delay?: number;
/**
* Specifies how many times the animation should be played. Default is 1.
* iOS animations support fractional iterations, i.e. 1.5.
* To repeat an animation infinitely, use Number.POSITIVE_INFINITY
*/
iterations?: number;
/**
* Specifies how many times the animation should be played. Default is 1.
* iOS animations support fractional iterations, i.e. 1.5.
* To repeat an animation infinitely, use Number.POSITIVE_INFINITY
*/
iterations?: number;
/**
* An optional animation curve. Possible values are contained in the [AnimationCurve enumeration](../modules/_ui_enums_.animationcurve.html).
* Alternatively, you can pass an instance of type UIViewAnimationCurve for iOS or android.animation.TimeInterpolator for Android.
*/
curve?: any;
/**
* An optional animation curve. Possible values are contained in the [AnimationCurve enumeration](../modules/_ui_enums_.animationcurve.html).
* Alternatively, you can pass an instance of type UIViewAnimationCurve for iOS or android.animation.TimeInterpolator for Android.
*/
curve?: any;
/**
* Determines whether the animation values will be applied on the animated object after the animation finishes.
*/
isForwards: boolean;
/**
* Determines whether the animation values will be applied on the animated object after the animation finishes.
*/
isForwards: boolean;
/**
* If true the animation will be played backwards.
*/
isReverse?: boolean;
/**
* If true the animation will be played backwards.
*/
isReverse?: boolean;
}
export class KeyframeAnimation {
/**
* The amount of time, in milliseconds, to delay starting the animation.
*/
delay: number;
/**
* The amount of time, in milliseconds, to delay starting the animation.
*/
delay: number;
/**
* Specifies how many times the animation should be played. Default is 1.
* iOS animations support fractional iterations, i.e. 1.5.
* To repeat an animation infinitely, use Number.POSITIVE_INFINITY
*/
iterations: number;
/**
* Specifies how many times the animation should be played. Default is 1.
* iOS animations support fractional iterations, i.e. 1.5.
* To repeat an animation infinitely, use Number.POSITIVE_INFINITY
*/
iterations: number;
/**
* Returns true if the application is currently running.
*/
isPlaying: boolean;
/**
* Returns true if the application is currently running.
*/
isPlaying: boolean;
/**
* Plays the animation.
*/
public play: (view: View) => Promise<void>;
/**
* Plays the animation.
*/
public play: (view: View) => Promise<void>;
/**
* Cancels a playing animation.
*/
public cancel: () => void;
/**
* Cancels a playing animation.
*/
public cancel: () => void;
/**
* Creates a keyframe animation from animation definition.
*/
public static keyframeAnimationFromInfo(info: KeyframeAnimationInfo): KeyframeAnimation;
/**
* Creates a keyframe animation from animation definition.
*/
public static keyframeAnimationFromInfo(info: KeyframeAnimationInfo): KeyframeAnimation;
}

View File

@@ -11,284 +11,284 @@ import { Animation } from '.';
import { backgroundColorProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty, rotateProperty, opacityProperty, rotateXProperty, rotateYProperty, widthProperty, heightProperty, PercentLength } from '../styling/style-properties';
export class Keyframes {
name: string;
keyframes: Array<UnparsedKeyframe>;
name: string;
keyframes: Array<UnparsedKeyframe>;
}
export class UnparsedKeyframe {
values: Array<any>;
declarations: Array<KeyframeDeclaration>;
values: Array<any>;
declarations: Array<KeyframeDeclaration>;
}
export class KeyframeDeclaration {
public property: string;
public value: any;
public property: string;
public value: any;
}
export class KeyframeInfo {
public duration: number;
public declarations: Array<KeyframeDeclaration>;
public curve?: any = AnimationCurve.ease;
public duration: number;
public declarations: Array<KeyframeDeclaration>;
public curve?: any = AnimationCurve.ease;
}
export class KeyframeAnimationInfo {
public keyframes: Array<KeyframeInfo>;
public name?: string = '';
public duration?: number = 0.3;
public delay?: number = 0;
public iterations?: number = 1;
public curve?: any = 'ease';
public isForwards?: boolean = false;
public isReverse?: boolean = false;
public keyframes: Array<KeyframeInfo>;
public name?: string = '';
public duration?: number = 0.3;
public delay?: number = 0;
public iterations?: number = 1;
public curve?: any = 'ease';
public isForwards?: boolean = false;
public isReverse?: boolean = false;
}
interface Keyframe {
backgroundColor?: Color;
scale?: { x: number; y: number };
translate?: { x: number; y: number };
rotate?: { x: number; y: number; z: number };
opacity?: number;
width?: PercentLength;
height?: PercentLength;
valueSource?: 'keyframe' | 'animation';
duration?: number;
curve?: any;
forceLayer?: boolean;
backgroundColor?: Color;
scale?: { x: number; y: number };
translate?: { x: number; y: number };
rotate?: { x: number; y: number; z: number };
opacity?: number;
width?: PercentLength;
height?: PercentLength;
valueSource?: 'keyframe' | 'animation';
duration?: number;
curve?: any;
forceLayer?: boolean;
}
export class KeyframeAnimation {
public animations: Array<Keyframe>;
public delay: number = 0;
public iterations: number = 1;
public animations: Array<Keyframe>;
public delay: number = 0;
public iterations: number = 1;
private _resolve;
private _isPlaying: boolean;
private _isForwards: boolean;
private _nativeAnimations: Array<Animation>;
private _target: View;
private _resolve;
private _isPlaying: boolean;
private _isForwards: boolean;
private _nativeAnimations: Array<Animation>;
private _target: View;
public static keyframeAnimationFromInfo(info: KeyframeAnimationInfo): KeyframeAnimation {
const length = info.keyframes.length;
let animations = new Array<Keyframe>();
let startDuration = 0;
public static keyframeAnimationFromInfo(info: KeyframeAnimationInfo): KeyframeAnimation {
const length = info.keyframes.length;
let animations = new Array<Keyframe>();
let startDuration = 0;
if (info.isReverse) {
for (let index = length - 1; index >= 0; index--) {
let keyframe = info.keyframes[index];
startDuration = KeyframeAnimation.parseKeyframe(info, keyframe, animations, startDuration);
}
} else {
for (let index = 0; index < length; index++) {
let keyframe = info.keyframes[index];
startDuration = KeyframeAnimation.parseKeyframe(info, keyframe, animations, startDuration);
}
for (let index = length - 1; index > 0; index--) {
let a1 = animations[index];
let a2 = animations[index - 1];
if (a2['curve'] !== undefined) {
a1['curve'] = a2['curve'];
a2['curve'] = undefined;
}
}
}
if (info.isReverse) {
for (let index = length - 1; index >= 0; index--) {
let keyframe = info.keyframes[index];
startDuration = KeyframeAnimation.parseKeyframe(info, keyframe, animations, startDuration);
}
} else {
for (let index = 0; index < length; index++) {
let keyframe = info.keyframes[index];
startDuration = KeyframeAnimation.parseKeyframe(info, keyframe, animations, startDuration);
}
for (let index = length - 1; index > 0; index--) {
let a1 = animations[index];
let a2 = animations[index - 1];
if (a2['curve'] !== undefined) {
a1['curve'] = a2['curve'];
a2['curve'] = undefined;
}
}
}
animations.map((a) => (a['curve'] ? a : Object.assign(a, { curve: info.curve })));
animations.map((a) => (a['curve'] ? a : Object.assign(a, { curve: info.curve })));
const animation: KeyframeAnimation = new KeyframeAnimation();
animation.delay = info.delay;
animation.iterations = info.iterations;
animation.animations = animations;
animation._isForwards = info.isForwards;
const animation: KeyframeAnimation = new KeyframeAnimation();
animation.delay = info.delay;
animation.iterations = info.iterations;
animation.animations = animations;
animation._isForwards = info.isForwards;
return animation;
}
return animation;
}
private static parseKeyframe(info: KeyframeAnimationInfo, keyframe: KeyframeInfo, animations: Array<Object>, startDuration: number): number {
let animation: Keyframe = {};
for (let declaration of keyframe.declarations) {
animation[declaration.property] = declaration.value;
}
private static parseKeyframe(info: KeyframeAnimationInfo, keyframe: KeyframeInfo, animations: Array<Object>, startDuration: number): number {
let animation: Keyframe = {};
for (let declaration of keyframe.declarations) {
animation[declaration.property] = declaration.value;
}
let duration = keyframe.duration;
if (duration === 0) {
duration = 0.01;
} else {
duration = info.duration * duration - startDuration;
startDuration += duration;
}
animation.duration = info.isReverse ? info.duration - duration : duration;
animation.curve = keyframe.curve;
animation.forceLayer = true;
animation.valueSource = 'keyframe';
animations.push(animation);
let duration = keyframe.duration;
if (duration === 0) {
duration = 0.01;
} else {
duration = info.duration * duration - startDuration;
startDuration += duration;
}
animation.duration = info.isReverse ? info.duration - duration : duration;
animation.curve = keyframe.curve;
animation.forceLayer = true;
animation.valueSource = 'keyframe';
animations.push(animation);
return startDuration;
}
return startDuration;
}
public get isPlaying(): boolean {
return this._isPlaying;
}
public get isPlaying(): boolean {
return this._isPlaying;
}
public cancel() {
if (!this.isPlaying) {
Trace.write('Keyframe animation is already playing.', Trace.categories.Animation, Trace.messageType.warn);
public cancel() {
if (!this.isPlaying) {
Trace.write('Keyframe animation is already playing.', Trace.categories.Animation, Trace.messageType.warn);
return;
}
return;
}
this._isPlaying = false;
for (let i = this._nativeAnimations.length - 1; i >= 0; i--) {
let animation = this._nativeAnimations[i];
if (animation.isPlaying) {
animation.cancel();
}
}
if (this._nativeAnimations.length > 0) {
let animation = this._nativeAnimations[0];
this._resetAnimationValues(this._target, animation);
}
this._resetAnimations();
}
this._isPlaying = false;
for (let i = this._nativeAnimations.length - 1; i >= 0; i--) {
let animation = this._nativeAnimations[i];
if (animation.isPlaying) {
animation.cancel();
}
}
if (this._nativeAnimations.length > 0) {
let animation = this._nativeAnimations[0];
this._resetAnimationValues(this._target, animation);
}
this._resetAnimations();
}
public play(view: View): Promise<void> {
if (this._isPlaying) {
Trace.write('Keyframe animation is already playing.', Trace.categories.Animation, Trace.messageType.warn);
public play(view: View): Promise<void> {
if (this._isPlaying) {
Trace.write('Keyframe animation is already playing.', Trace.categories.Animation, Trace.messageType.warn);
return new Promise<void>((resolve) => {
resolve();
});
}
return new Promise<void>((resolve) => {
resolve();
});
}
let animationFinishedPromise = new Promise<void>((resolve) => {
this._resolve = resolve;
});
let animationFinishedPromise = new Promise<void>((resolve) => {
this._resolve = resolve;
});
this._isPlaying = true;
this._nativeAnimations = new Array<Animation>();
this._target = view;
this._isPlaying = true;
this._nativeAnimations = new Array<Animation>();
this._target = view;
if (this.delay !== 0) {
setTimeout(() => this.animate(view, 0, this.iterations), this.delay);
} else {
this.animate(view, 0, this.iterations);
}
if (this.delay !== 0) {
setTimeout(() => this.animate(view, 0, this.iterations), this.delay);
} else {
this.animate(view, 0, this.iterations);
}
return animationFinishedPromise;
}
return animationFinishedPromise;
}
private animate(view: View, index: number, iterations: number) {
if (!this._isPlaying) {
return;
}
if (index === 0) {
let animation = this.animations[0];
private animate(view: View, index: number, iterations: number) {
if (!this._isPlaying) {
return;
}
if (index === 0) {
let animation = this.animations[0];
if ('backgroundColor' in animation) {
view.style[backgroundColorProperty.keyframe] = animation.backgroundColor;
}
if ('scale' in animation) {
view.style[scaleXProperty.keyframe] = animation.scale.x;
view.style[scaleYProperty.keyframe] = animation.scale.y;
}
if ('translate' in animation) {
view.style[translateXProperty.keyframe] = animation.translate.x;
view.style[translateYProperty.keyframe] = animation.translate.y;
}
if ('rotate' in animation) {
view.style[rotateXProperty.keyframe] = animation.rotate.x;
view.style[rotateYProperty.keyframe] = animation.rotate.y;
view.style[rotateProperty.keyframe] = animation.rotate.z;
}
if ('opacity' in animation) {
view.style[opacityProperty.keyframe] = animation.opacity;
}
if ('height' in animation) {
view.style[heightProperty.keyframe] = animation.height;
}
if ('width' in animation) {
view.style[widthProperty.keyframe] = animation.width;
}
if ('backgroundColor' in animation) {
view.style[backgroundColorProperty.keyframe] = animation.backgroundColor;
}
if ('scale' in animation) {
view.style[scaleXProperty.keyframe] = animation.scale.x;
view.style[scaleYProperty.keyframe] = animation.scale.y;
}
if ('translate' in animation) {
view.style[translateXProperty.keyframe] = animation.translate.x;
view.style[translateYProperty.keyframe] = animation.translate.y;
}
if ('rotate' in animation) {
view.style[rotateXProperty.keyframe] = animation.rotate.x;
view.style[rotateYProperty.keyframe] = animation.rotate.y;
view.style[rotateProperty.keyframe] = animation.rotate.z;
}
if ('opacity' in animation) {
view.style[opacityProperty.keyframe] = animation.opacity;
}
if ('height' in animation) {
view.style[heightProperty.keyframe] = animation.height;
}
if ('width' in animation) {
view.style[widthProperty.keyframe] = animation.width;
}
setTimeout(() => this.animate(view, 1, iterations), 1);
} else if (index < 0 || index >= this.animations.length) {
iterations -= 1;
if (iterations > 0) {
this.animate(view, 0, iterations);
} else {
if (this._isForwards === false) {
let animation = this.animations[this.animations.length - 1];
this._resetAnimationValues(view, animation);
}
this._resolveAnimationFinishedPromise();
}
} else {
let animation;
const cachedAnimation = this._nativeAnimations[index - 1];
setTimeout(() => this.animate(view, 1, iterations), 1);
} else if (index < 0 || index >= this.animations.length) {
iterations -= 1;
if (iterations > 0) {
this.animate(view, 0, iterations);
} else {
if (this._isForwards === false) {
let animation = this.animations[this.animations.length - 1];
this._resetAnimationValues(view, animation);
}
this._resolveAnimationFinishedPromise();
}
} else {
let animation;
const cachedAnimation = this._nativeAnimations[index - 1];
if (cachedAnimation) {
animation = cachedAnimation;
} else {
let animationDef = this.animations[index];
(<any>animationDef).target = view;
animation = new Animation([animationDef]);
this._nativeAnimations.push(animation);
}
if (cachedAnimation) {
animation = cachedAnimation;
} else {
let animationDef = this.animations[index];
(<any>animationDef).target = view;
animation = new Animation([animationDef]);
this._nativeAnimations.push(animation);
}
const isLastIteration = iterations - 1 <= 0;
const isLastIteration = iterations - 1 <= 0;
// Catch the animation cancel to prevent unhandled promise rejection warnings
animation
.play(isLastIteration)
.then(
() => {
this.animate(view, index + 1, iterations);
},
(error: any) => {
Trace.write(typeof error === 'string' ? error : error.message, Trace.categories.Animation, Trace.messageType.warn);
}
)
.catch((error: any) => {
Trace.write(typeof error === 'string' ? error : error.message, Trace.categories.Animation, Trace.messageType.warn);
}); // tslint:disable-line
}
}
// Catch the animation cancel to prevent unhandled promise rejection warnings
animation
.play(isLastIteration)
.then(
() => {
this.animate(view, index + 1, iterations);
},
(error: any) => {
Trace.write(typeof error === 'string' ? error : error.message, Trace.categories.Animation, Trace.messageType.warn);
}
)
.catch((error: any) => {
Trace.write(typeof error === 'string' ? error : error.message, Trace.categories.Animation, Trace.messageType.warn);
}); // tslint:disable-line
}
}
public _resolveAnimationFinishedPromise() {
this._nativeAnimations = new Array<Animation>();
this._isPlaying = false;
this._target = null;
this._resolve();
}
public _resolveAnimationFinishedPromise() {
this._nativeAnimations = new Array<Animation>();
this._isPlaying = false;
this._target = null;
this._resolve();
}
public _resetAnimations() {
this._nativeAnimations = new Array<Animation>();
this._isPlaying = false;
this._target = null;
}
public _resetAnimations() {
this._nativeAnimations = new Array<Animation>();
this._isPlaying = false;
this._target = null;
}
private _resetAnimationValues(view: View, animation: Object) {
if ('backgroundColor' in animation) {
view.style[backgroundColorProperty.keyframe] = unsetValue;
}
if ('scale' in animation) {
view.style[scaleXProperty.keyframe] = unsetValue;
view.style[scaleYProperty.keyframe] = unsetValue;
}
if ('translate' in animation) {
view.style[translateXProperty.keyframe] = unsetValue;
view.style[translateYProperty.keyframe] = unsetValue;
}
if ('rotate' in animation) {
view.style[rotateProperty.keyframe] = unsetValue;
}
if ('opacity' in animation) {
view.style[opacityProperty.keyframe] = unsetValue;
}
if ('height' in animation) {
view.style[heightProperty.keyframe] = unsetValue;
}
if ('width' in animation) {
view.style[widthProperty.keyframe] = unsetValue;
}
}
private _resetAnimationValues(view: View, animation: Object) {
if ('backgroundColor' in animation) {
view.style[backgroundColorProperty.keyframe] = unsetValue;
}
if ('scale' in animation) {
view.style[scaleXProperty.keyframe] = unsetValue;
view.style[scaleYProperty.keyframe] = unsetValue;
}
if ('translate' in animation) {
view.style[translateXProperty.keyframe] = unsetValue;
view.style[translateYProperty.keyframe] = unsetValue;
}
if ('rotate' in animation) {
view.style[rotateProperty.keyframe] = unsetValue;
}
if ('opacity' in animation) {
view.style[opacityProperty.keyframe] = unsetValue;
}
if ('height' in animation) {
view.style[heightProperty.keyframe] = unsetValue;
}
if ('width' in animation) {
view.style[widthProperty.keyframe] = unsetValue;
}
}
}