mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
This adds the ability to Cancel the Animation via the Promise returned via a play command.
This commit is contained in:
@ -83,21 +83,69 @@ export var test_CancellingAnimation = function (done) {
|
|||||||
// <snippet module="ui/animation" title="animation">
|
// <snippet module="ui/animation" title="animation">
|
||||||
// # Cancelling animation
|
// # Cancelling animation
|
||||||
// ``` JavaScript
|
// ``` JavaScript
|
||||||
var animation1 = label.createAnimation({ translate: { x: 100, y: 100 } });
|
var animation1 = label.createAnimation({ translate: { x: 100, y: 100}, duration: 500 });
|
||||||
animation1.play()
|
animation1.play()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
////console.log("Animation finished");
|
////console.log("Animation finished");
|
||||||
// <hide>
|
// <hide>
|
||||||
assertIOSNativeTransformIsCorrect(label);
|
throw new Error("Cancelling Animation - Should not be in the Promise Then()");
|
||||||
helper.goBack();
|
|
||||||
done();
|
|
||||||
// </hide>
|
// </hide>
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
////console.log("Animation cancelled");
|
////console.log("Animation cancelled");
|
||||||
// <hide>
|
// <hide>
|
||||||
helper.goBack();
|
helper.goBack();
|
||||||
done();
|
if (!e) {
|
||||||
|
done(new Error("Cancel path did not have proper error"));
|
||||||
|
} else if (e.toString() === "Error: Animation cancelled.") {
|
||||||
|
done()
|
||||||
|
} else {
|
||||||
|
done(e);
|
||||||
|
}
|
||||||
|
// </hide>
|
||||||
|
});
|
||||||
|
animation1.cancel();
|
||||||
|
// ```
|
||||||
|
// </snippet>
|
||||||
|
}
|
||||||
|
|
||||||
|
export var test_CancellingAnimate = function (done) {
|
||||||
|
var mainPage: pageModule.Page;
|
||||||
|
var label: labelModule.Label;
|
||||||
|
var pageFactory = function (): pageModule.Page {
|
||||||
|
label = new labelModule.Label();
|
||||||
|
label.text = "label";
|
||||||
|
var stackLayout = new stackLayoutModule.StackLayout();
|
||||||
|
stackLayout.addChild(label);
|
||||||
|
mainPage = new pageModule.Page();
|
||||||
|
mainPage.content = stackLayout;
|
||||||
|
return mainPage;
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.navigate(pageFactory);
|
||||||
|
TKUnit.waitUntilReady(() => { return label.isLoaded });
|
||||||
|
|
||||||
|
// <snippet module="ui/animation" title="animation">
|
||||||
|
// # Cancelling animation
|
||||||
|
// ``` JavaScript
|
||||||
|
var animation1 = label.animate({ translate: { x: 100, y: 100 }, duration: 500 })
|
||||||
|
.then(() => {
|
||||||
|
////console.log("Animation finished");
|
||||||
|
// <hide>
|
||||||
|
throw new Error("Cancelling Animate - Should not be in Promise Then()");
|
||||||
|
// </hide>
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
////console.log("Animation cancelled");
|
||||||
|
// <hide>
|
||||||
|
helper.goBack();
|
||||||
|
if (!e) {
|
||||||
|
done(new Error("Cancel path did not have proper error"));
|
||||||
|
} else if (e.toString() === "Error: Animation cancelled.") {
|
||||||
|
done()
|
||||||
|
} else {
|
||||||
|
done(e);
|
||||||
|
}
|
||||||
// </hide>
|
// </hide>
|
||||||
});
|
});
|
||||||
animation1.cancel();
|
animation1.cancel();
|
||||||
|
@ -42,6 +42,14 @@ export class CubicBezierAnimationCurve implements definition.CubicBezierAnimatio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a BOGUS Class to make TypeScript happy - This is not needed other than to make TS happy.
|
||||||
|
// We didn't want to actually modify Promise; as the cancel() is ONLY valid for animations "Promise"
|
||||||
|
export class AnimationPromise implements definition.AnimationPromise {
|
||||||
|
public cancel(): void { /* Do Nothing */ }
|
||||||
|
public then(onFulfilled?: (value?: any) => void, onRejected?: (error?: any) => void): AnimationPromise { return new AnimationPromise();}
|
||||||
|
public catch(onRejected?: (error?: any) => void): AnimationPromise { return new AnimationPromise();}
|
||||||
|
}
|
||||||
|
|
||||||
export class Animation implements definition.Animation {
|
export class Animation implements definition.Animation {
|
||||||
public _propertyAnimations: Array<PropertyAnimation>;
|
public _propertyAnimations: Array<PropertyAnimation>;
|
||||||
public _playSequentially: boolean;
|
public _playSequentially: boolean;
|
||||||
@ -49,20 +57,44 @@ export class Animation implements definition.Animation {
|
|||||||
private _resolve;
|
private _resolve;
|
||||||
private _reject;
|
private _reject;
|
||||||
|
|
||||||
public play(): Promise<void> {
|
public play(): AnimationPromise {
|
||||||
if (this.isPlaying) {
|
if (this.isPlaying) {
|
||||||
throw new Error("Animation is already playing.");
|
throw new Error("Animation is already playing.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var animationFinishedPromise = new Promise<void>((resolve, reject) => {
|
// 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
|
||||||
|
var animationFinishedPromise = <AnimationPromise>new Promise<void>((resolve, reject) => {
|
||||||
this._resolve = resolve;
|
this._resolve = resolve;
|
||||||
this._reject = reject;
|
this._reject = reject;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.fixupAnimationPromise(animationFinishedPromise);
|
||||||
|
|
||||||
this._isPlaying = true;
|
this._isPlaying = true;
|
||||||
return animationFinishedPromise;
|
return animationFinishedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fixupAnimationPromise(promise: AnimationPromise): void {
|
||||||
|
// Since we are using function() below because of arguments, TS won't automatically do a _this for those functions.
|
||||||
|
var _this = this;
|
||||||
|
promise.cancel = () => {
|
||||||
|
_this.cancel();
|
||||||
|
};
|
||||||
|
var _then = promise.then;
|
||||||
|
promise.then = function() {
|
||||||
|
var r = _then.apply(promise, arguments);
|
||||||
|
_this.fixupAnimationPromise(r);
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
var _catch = promise.catch;
|
||||||
|
promise.catch = function() {
|
||||||
|
var r = _catch.apply(promise, arguments);
|
||||||
|
_this.fixupAnimationPromise(r);
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
if (!this.isPlaying) {
|
if (!this.isPlaying) {
|
||||||
throw new Error("Animation is not currently playing.");
|
throw new Error("Animation is not currently playing.");
|
||||||
|
@ -31,7 +31,7 @@ export class Animation extends common.Animation implements definition.Animation
|
|||||||
private _propertyUpdateCallbacks: Array<Function>;
|
private _propertyUpdateCallbacks: Array<Function>;
|
||||||
private _propertyResetCallbacks: Array<Function>;
|
private _propertyResetCallbacks: Array<Function>;
|
||||||
|
|
||||||
public play(): Promise<void> {
|
public play(): definition.AnimationPromise {
|
||||||
var animationFinishedPromise = super.play();
|
var animationFinishedPromise = super.play();
|
||||||
|
|
||||||
var i: number;
|
var i: number;
|
||||||
|
13
ui/animation/animation.d.ts
vendored
13
ui/animation/animation.d.ts
vendored
@ -82,12 +82,23 @@
|
|||||||
y: number;
|
y: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Promise that can cancel the animation, we have to pretend our returns itself along with the cancel
|
||||||
|
*/
|
||||||
|
export class AnimationPromise extends Promise<void> {
|
||||||
|
cancel(): void;
|
||||||
|
then(onFulfilled?: (value?: any) => Thenable<void>, onRejected?: (error?: any) => Thenable<void>): AnimationPromise;
|
||||||
|
then(onFulfilled?: (value?: any) => void, onRejected?: (error?: any) => void): AnimationPromise;
|
||||||
|
catch(onRejected?: (error?: any) => Thenable<void>): AnimationPromise;
|
||||||
|
catch(onRejected?: (error?: any) => void): AnimationPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a animation set.
|
* Defines a animation set.
|
||||||
*/
|
*/
|
||||||
export class Animation {
|
export class Animation {
|
||||||
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
|
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
|
||||||
public play: () => Promise<void>;
|
public play: () => AnimationPromise;
|
||||||
public cancel: () => void;
|
public cancel: () => void;
|
||||||
public isPlaying: boolean;
|
public isPlaying: boolean;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ export class Animation extends common.Animation implements definition.Animation
|
|||||||
private _cancelledAnimations: number;
|
private _cancelledAnimations: number;
|
||||||
private _mergedPropertyAnimations: Array<common.PropertyAnimation>;
|
private _mergedPropertyAnimations: Array<common.PropertyAnimation>;
|
||||||
|
|
||||||
public play(): Promise<void> {
|
public play(): definition.AnimationPromise {
|
||||||
var animationFinishedPromise = super.play();
|
var animationFinishedPromise = super.play();
|
||||||
this._finishedAnimations = 0;
|
this._finishedAnimations = 0;
|
||||||
this._cancelledAnimations = 0;
|
this._cancelledAnimations = 0;
|
||||||
|
@ -1164,7 +1164,7 @@ export class View extends ProxyObject implements definition.View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public animate(animation: any): Promise<void> {
|
public animate(animation: any): animModule.AnimationPromise {
|
||||||
return this.createAnimation(animation).play();
|
return this.createAnimation(animation).play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
ui/core/view.d.ts
vendored
2
ui/core/view.d.ts
vendored
@ -518,7 +518,7 @@ declare module "ui/core/view" {
|
|||||||
/**
|
/**
|
||||||
* Animates one or more properties of the view based on the supplied options.
|
* Animates one or more properties of the view based on the supplied options.
|
||||||
*/
|
*/
|
||||||
public animate(options: animation.AnimationDefinition): Promise<void>;
|
public animate(options: animation.AnimationDefinition): animation.AnimationPromise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an Animation object based on the supplied options.
|
* Creates an Animation object based on the supplied options.
|
||||||
|
Reference in New Issue
Block a user