mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 05:18:39 +08:00
Merge pull request #791 from NativeScript/hristov/issue-774
Fixed: If an Animation instance is played more than once, the same pr…
This commit is contained in:
@ -38,8 +38,8 @@ export function onSlideOut(args: observable.EventData) {
|
|||||||
|
|
||||||
panelAnimation = panel.createAnimation({ opacity: 0, scale: { x: 0.5, y: 0.5 }, rotate: -360, backgroundColor: new colorModule.Color("red"), duration: vm.duration, iterations: vm.iterations });
|
panelAnimation = panel.createAnimation({ opacity: 0, scale: { x: 0.5, y: 0.5 }, rotate: -360, backgroundColor: new colorModule.Color("red"), duration: vm.duration, iterations: vm.iterations });
|
||||||
|
|
||||||
buttonAnimation.play().finished
|
buttonAnimation.play()
|
||||||
.then(() => panelAnimation.play().finished)
|
.then(() => panelAnimation.play())
|
||||||
.catch((e) => console.log(e.message));
|
.catch((e) => console.log(e.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +56,8 @@ export function onSlideIn(args: observable.EventData) {
|
|||||||
]
|
]
|
||||||
buttonAnimation = new animationModule.Animation(buttonAnimations, vm.playSequentially);
|
buttonAnimation = new animationModule.Animation(buttonAnimations, vm.playSequentially);
|
||||||
|
|
||||||
panelAnimation.play().finished
|
panelAnimation.play()
|
||||||
.then(() => buttonAnimation.play().finished)
|
.then(() => buttonAnimation.play())
|
||||||
.catch((e) => console.log(e.message));
|
.catch((e) => console.log(e.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ export var test_CancellingAnimation = function (done) {
|
|||||||
// # Cancelling animation
|
// # Cancelling animation
|
||||||
// ``` JavaScript
|
// ``` JavaScript
|
||||||
var animation1 = label.createAnimation({ translate: { x: 100, y: 100 } });
|
var animation1 = label.createAnimation({ translate: { x: 100, y: 100 } });
|
||||||
animation1.play().finished
|
animation1.play()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
////console.log("Animation finished");
|
////console.log("Animation finished");
|
||||||
// <hide>
|
// <hide>
|
||||||
@ -145,51 +145,51 @@ export var test_ChainingAnimations = function (done) {
|
|||||||
// </snippet>
|
// </snippet>
|
||||||
}
|
}
|
||||||
|
|
||||||
//export var test_ReusingAnimations = function (done) {
|
export var test_ReusingAnimations = function (done) {
|
||||||
// var mainPage: pageModule.Page;
|
var mainPage: pageModule.Page;
|
||||||
// var label: labelModule.Label;
|
var label: labelModule.Label;
|
||||||
// var pageFactory = function (): pageModule.Page {
|
var pageFactory = function (): pageModule.Page {
|
||||||
// label = new labelModule.Label();
|
label = new labelModule.Label();
|
||||||
// label.text = "label";
|
label.text = "label";
|
||||||
// var stackLayout = new stackLayoutModule.StackLayout();
|
var stackLayout = new stackLayoutModule.StackLayout();
|
||||||
// stackLayout.addChild(label);
|
stackLayout.addChild(label);
|
||||||
// mainPage = new pageModule.Page();
|
mainPage = new pageModule.Page();
|
||||||
// mainPage.content = stackLayout;
|
mainPage.content = stackLayout;
|
||||||
// return mainPage;
|
return mainPage;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// helper.navigate(pageFactory);
|
helper.navigate(pageFactory);
|
||||||
// TKUnit.waitUntilReady(() => { return label.isLoaded });
|
TKUnit.waitUntilReady(() => { return label.isLoaded });
|
||||||
|
|
||||||
// // <snippet module="ui/animation" title="animation">
|
// <snippet module="ui/animation" title="animation">
|
||||||
// // # Reusing animations
|
// # Reusing animations
|
||||||
// // ``` JavaScript
|
// ``` JavaScript
|
||||||
// var animation1 = label.createAnimation({ translate: { x: 100, y: 100 } });
|
var animation1 = label.createAnimation({ translate: { x: 100, y: 100 } });
|
||||||
// var animation2 = label.createAnimation({ translate: { x: 0, y: 0 } });
|
var animation2 = label.createAnimation({ translate: { x: 0, y: 0 } });
|
||||||
|
|
||||||
// animation1.play().finished
|
animation1.play()
|
||||||
// .then(() => animation1.play().finished)
|
.then(() => animation2.play())
|
||||||
// .then(() => animation1.play().finished)
|
.then(() => animation1.play())
|
||||||
// .then(() => animation2.play().finished)
|
.then(() => animation2.play())
|
||||||
// .then(() => animation1.play().finished)
|
.then(() => animation1.play())
|
||||||
// .then(() => animation2.play().finished)
|
.then(() => animation2.play())
|
||||||
// .then(() => {
|
.then(() => {
|
||||||
// ////console.log("Animation finished");
|
////console.log("Animation finished");
|
||||||
// // <hide>
|
// <hide>
|
||||||
// helper.goBack();
|
helper.goBack();
|
||||||
// done();
|
done();
|
||||||
// // </hide>
|
// </hide>
|
||||||
// })
|
})
|
||||||
// .catch((e) => {
|
.catch((e) => {
|
||||||
// console.log(e.message);
|
console.log(e.message);
|
||||||
// // <hide>
|
// <hide>
|
||||||
// helper.goBack();
|
helper.goBack();
|
||||||
// done(e);
|
done(e);
|
||||||
// // </hide>
|
// </hide>
|
||||||
// });
|
});
|
||||||
// // ```
|
// ```
|
||||||
// // </snippet>
|
// </snippet>
|
||||||
//}
|
}
|
||||||
|
|
||||||
export var test_AnimatingMultipleViews = function (done) {
|
export var test_AnimatingMultipleViews = function (done) {
|
||||||
var mainPage: pageModule.Page;
|
var mainPage: pageModule.Page;
|
||||||
@ -223,7 +223,7 @@ export var test_AnimatingMultipleViews = function (done) {
|
|||||||
{ target: label3, translate: { x: 200, y: 200 }, duration: 1000, delay: 666 },
|
{ target: label3, translate: { x: 200, y: 200 }, duration: 1000, delay: 666 },
|
||||||
];
|
];
|
||||||
var a = new animation.Animation(animations);
|
var a = new animation.Animation(animations);
|
||||||
a.play().finished
|
a.play()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
////console.log("Animations finished");
|
////console.log("Animations finished");
|
||||||
// <hide>
|
// <hide>
|
||||||
@ -404,10 +404,13 @@ export var test_AnimationsAreAlwaysPlayed = function (done) {
|
|||||||
var animation1 = label.createAnimation({ opacity: 0 });
|
var animation1 = label.createAnimation({ opacity: 0 });
|
||||||
var animation2 = label.createAnimation({ opacity: 1 });
|
var animation2 = label.createAnimation({ opacity: 1 });
|
||||||
|
|
||||||
animation1.play().finished
|
animation1.play()
|
||||||
.then(() => animation2.play().finished)
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
TKUnit.assert(label.opacity === 1, `Label opacity expected vaue is 1, actual value is ${label.opacity}.`);
|
TKUnit.assert(label.opacity === 0, `Label opacity should be 0 after first animation, actual value is ${label.opacity}.`);
|
||||||
|
return animation2.play()
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
TKUnit.assert(label.opacity === 1, `Label opacity should be 1 after second animation, actual value is ${label.opacity}.`);
|
||||||
helper.goBack();
|
helper.goBack();
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
@ -417,3 +420,65 @@ export var test_AnimationsAreAlwaysPlayed = function (done) {
|
|||||||
done(e);
|
done(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export var test_PlayPromiseIsResolvedWhenAnimationFinishes = 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 });
|
||||||
|
|
||||||
|
var animation = label.createAnimation({ opacity: 0, duration: 1000 });
|
||||||
|
|
||||||
|
animation.play()
|
||||||
|
.then(function onResolved() {
|
||||||
|
TKUnit.assert(animation.isPlaying === false, "Animation.isPlaying should be false when animation play promise is resolved.");
|
||||||
|
helper.goBack();
|
||||||
|
done();
|
||||||
|
}, function onRejected(e) {
|
||||||
|
TKUnit.assert(1 === 2, "Animation play promise should be resolved, not rejected.");
|
||||||
|
helper.goBack();
|
||||||
|
done(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export var test_PlayPromiseIsRejectedWhenAnimationIsCancelled = 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 });
|
||||||
|
|
||||||
|
var animation = label.createAnimation({ opacity: 0, duration: 1000 });
|
||||||
|
|
||||||
|
animation.play()
|
||||||
|
.then(function onResolved() {
|
||||||
|
TKUnit.assert(1 === 2, "Animation play promise should be rejected, not resolved.");
|
||||||
|
helper.goBack();
|
||||||
|
done();
|
||||||
|
}, function onRejected(e) {
|
||||||
|
TKUnit.assert(animation.isPlaying === false, "Animation.isPlaying should be false when animation play promise is rejected.");
|
||||||
|
helper.goBack();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
animation.cancel();
|
||||||
|
}
|
@ -26,15 +26,19 @@ export class Animation implements definition.Animation {
|
|||||||
private _isPlaying: boolean;
|
private _isPlaying: boolean;
|
||||||
private _resolve;
|
private _resolve;
|
||||||
private _reject;
|
private _reject;
|
||||||
private _animationFinishedPromise: Promise<void>;
|
|
||||||
|
|
||||||
public play(): Animation {
|
public play(): Promise<void> {
|
||||||
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) => {
|
||||||
|
this._resolve = resolve;
|
||||||
|
this._reject = reject;
|
||||||
|
});
|
||||||
|
|
||||||
this._isPlaying = true;
|
this._isPlaying = true;
|
||||||
return this;
|
return animationFinishedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
@ -43,10 +47,6 @@ export class Animation implements definition.Animation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get finished(): Promise<void> {
|
|
||||||
return this._animationFinishedPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get isPlaying(): boolean {
|
public get isPlaying(): boolean {
|
||||||
return this._isPlaying;
|
return this._isPlaying;
|
||||||
}
|
}
|
||||||
@ -70,11 +70,6 @@ export class Animation implements definition.Animation {
|
|||||||
trace.write("Created " + this._propertyAnimations.length + " individual property animations.", trace.categories.Animation);
|
trace.write("Created " + this._propertyAnimations.length + " individual property animations.", trace.categories.Animation);
|
||||||
|
|
||||||
this._playSequentially = playSequentially;
|
this._playSequentially = playSequentially;
|
||||||
var that = this;
|
|
||||||
this._animationFinishedPromise = new Promise<void>((resolve, reject) => {
|
|
||||||
that._resolve = resolve;
|
|
||||||
that._reject = reject;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public _resolveAnimationFinishedPromise() {
|
public _resolveAnimationFinishedPromise() {
|
||||||
|
@ -18,8 +18,8 @@ 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(): Animation {
|
public play(): Promise<void> {
|
||||||
super.play();
|
var animationFinishedPromise = super.play();
|
||||||
|
|
||||||
var i: number;
|
var i: number;
|
||||||
var length: number;
|
var length: number;
|
||||||
@ -34,12 +34,6 @@ export class Animation extends common.Animation implements definition.Animation
|
|||||||
this._createAnimators(this._propertyAnimations[i]);
|
this._createAnimators(this._propertyAnimations[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._animators.length === 0) {
|
|
||||||
trace.write("Nothing to animate.", trace.categories.Animation);
|
|
||||||
this._resolveAnimationFinishedPromise();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._nativeAnimatorsArray = java.lang.reflect.Array.newInstance(android.animation.Animator.class, this._animators.length);
|
this._nativeAnimatorsArray = java.lang.reflect.Array.newInstance(android.animation.Animator.class, this._animators.length);
|
||||||
i = 0;
|
i = 0;
|
||||||
length = this._animators.length;
|
length = this._animators.length;
|
||||||
@ -58,7 +52,7 @@ export class Animation extends common.Animation implements definition.Animation
|
|||||||
|
|
||||||
trace.write("Starting " + this._nativeAnimatorsArray.length + " animations " + (this._playSequentially ? "sequentially." : "together."), trace.categories.Animation);
|
trace.write("Starting " + this._nativeAnimatorsArray.length + " animations " + (this._playSequentially ? "sequentially." : "together."), trace.categories.Animation);
|
||||||
this._animatorSet.start();
|
this._animatorSet.start();
|
||||||
return this;
|
return animationFinishedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
|
3
ui/animation/animation.d.ts
vendored
3
ui/animation/animation.d.ts
vendored
@ -72,9 +72,8 @@
|
|||||||
*/
|
*/
|
||||||
export class Animation {
|
export class Animation {
|
||||||
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
|
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
|
||||||
public play: () => Animation;
|
public play: () => Promise<void>;
|
||||||
public cancel: () => void;
|
public cancel: () => void;
|
||||||
public finished: Promise<void>;
|
|
||||||
public isPlaying: boolean;
|
public isPlaying: boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -46,14 +46,14 @@ 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(): Animation {
|
public play(): Promise<void> {
|
||||||
super.play();
|
var animationFinishedPromise = super.play();
|
||||||
|
|
||||||
this._finishedAnimations = 0;
|
this._finishedAnimations = 0;
|
||||||
this._cancelledAnimations = 0;
|
this._cancelledAnimations = 0;
|
||||||
this._iOSAnimationFunction();
|
|
||||||
|
|
||||||
return this;
|
this._iOSAnimationFunction();
|
||||||
|
return animationFinishedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
|
@ -1099,7 +1099,7 @@ export class View extends proxy.ProxyObject implements definition.View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public animate(animation: animationModule.AnimationDefinition): Promise<void> {
|
public animate(animation: animationModule.AnimationDefinition): Promise<void> {
|
||||||
return this.createAnimation(animation).play().finished;
|
return this.createAnimation(animation).play();
|
||||||
}
|
}
|
||||||
|
|
||||||
public createAnimation(animation: animationModule.AnimationDefinition): animationModule.Animation {
|
public createAnimation(animation: animationModule.AnimationDefinition): animationModule.Animation {
|
||||||
|
Reference in New Issue
Block a user