mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
Merge pull request #936 from NativeScript/cankov/animate-transform-sequence
Subsequent animation of transition and rotation or scale will appear jumpy in iOS
This commit is contained in:
@ -90,4 +90,75 @@ export function onSingle(args: observable.EventData) {
|
||||
})
|
||||
.then(() => console.log("Animation finished"))
|
||||
.catch((e) => console.log(e.message));
|
||||
}
|
||||
|
||||
export function onSequence(args: observable.EventData) {
|
||||
console.log("onSequence");
|
||||
|
||||
button3.animate({
|
||||
translate: { x: 80, y: -40 },
|
||||
scale: { x: 0.9, y: 0.3 },
|
||||
rotate: 25,
|
||||
duration: 1000
|
||||
})
|
||||
.then(() => button3.animate({
|
||||
translate: { x: 0, y: -80 },
|
||||
scale: { x: 0.5, y: 0.5 },
|
||||
rotate: -25,
|
||||
duration: 1000
|
||||
}))
|
||||
.then(() => button3.animate({
|
||||
translate: { x: -80, y: -40 },
|
||||
scale: { x: 0.5, y: 0.9 },
|
||||
rotate: 45,
|
||||
duration: 1000
|
||||
}))
|
||||
.then(() => button3.animate({
|
||||
translate: { x: 0, y: 0 },
|
||||
scale: { x: 1, y: 1 },
|
||||
rotate: 0,
|
||||
duration: 1000
|
||||
}))
|
||||
.then(() => console.log("Animation finished"))
|
||||
.catch((e) => console.log(e.message));
|
||||
}
|
||||
|
||||
export function onInterrupted(args: observable.EventData) {
|
||||
console.log("onInterrupt");
|
||||
|
||||
setTimeout(() => {
|
||||
button3.animate({
|
||||
translate: { x: 80, y: -40 },
|
||||
scale: { x: 0.9, y: 0.3 },
|
||||
rotate: 25,
|
||||
duration: 1000
|
||||
});
|
||||
}, 700 * 0);
|
||||
|
||||
setTimeout(function() {
|
||||
button3.animate({
|
||||
translate: { x: 0, y: -80 },
|
||||
scale: { x: 0.5, y: 0.5 },
|
||||
rotate: -25,
|
||||
duration: 1000
|
||||
})
|
||||
}, 700 * 1);
|
||||
|
||||
setTimeout(function() {
|
||||
button3.animate({
|
||||
translate: { x: -80, y: -40 },
|
||||
scale: { x: 0.5, y: 0.9 },
|
||||
rotate: 45,
|
||||
duration: 1000
|
||||
})
|
||||
}, 700 * 2);
|
||||
|
||||
setTimeout(function() {
|
||||
button3.animate({
|
||||
translate: { x: 0, y: 0 },
|
||||
scale: { x: 1, y: 1 },
|
||||
rotate: 0,
|
||||
duration: 1000
|
||||
})
|
||||
}, 700 * 3);
|
||||
}
|
@ -2,29 +2,34 @@
|
||||
<StackLayout orientation="vertical">
|
||||
<StackLayout orientation="vertical" backgroundColor="LightGray" paddingTop="5" paddingBottom="5">
|
||||
|
||||
<Label text="{{ duration, 'Duration: ' + duration + ' ms' }}" width="180" marginTop="5" marginBottom="5"/>
|
||||
<Slider minValue="0" maxValue="10000" value="{{ duration }}" marginTop="5" marginBottom="5" marginLeft="10" marginRight="10"/>
|
||||
<Label text="{{ duration, 'Duration: ' + duration + ' ms' }}" width="180" />
|
||||
<Slider minValue="0" maxValue="10000" value="{{ duration }}" margin="0 15" />
|
||||
|
||||
<Label text="{{ iterations, 'Iterations: ' + iterations + ' times' }}" width="180" marginTop="5" marginBottom="5"/>
|
||||
<Slider minValue="0" maxValue="10" value="{{ iterations }}" marginTop="5" marginBottom="5" marginLeft="10" marginRight="10"/>
|
||||
<Label text="{{ iterations, 'Iterations: ' + iterations + ' times' }}" width="180" />
|
||||
<Slider minValue="0" maxValue="10" value="{{ iterations }}" margin="0 15" />
|
||||
|
||||
<StackLayout orientation="horizontal" marginTop="5" marginBottom="5" horizontalAlignment="center">
|
||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
||||
<Label text="Play Sequentially?"/>
|
||||
<Switch marginLeft="10" checked="{{ playSequentially }}"/>
|
||||
</StackLayout>
|
||||
|
||||
|
||||
<StackLayout orientation="horizontal" marginTop="5" marginBottom="5" horizontalAlignment="center" paddingLeft="5" paddingRight="5">
|
||||
<Button text="Out" tap="onSlideOut" width="75" marginLeft="5" marginRight="5" />
|
||||
<Button text="In" tap="onSlideIn" width="75" marginLeft="5" marginRight="5" />
|
||||
<Button text="Single" tap="onSingle" width="75" marginLeft="5" marginRight="5" />
|
||||
<Button text="Cancel" tap="onCancel" width="75" marginLeft="5" marginRight="5" />
|
||||
<Button text="Out" tap="onSlideOut" width="40" marginLeft="5" marginRight="5" />
|
||||
<Button text="In" tap="onSlideIn" width="40" marginLeft="5" marginRight="5" />
|
||||
<Button text="Single" tap="onSingle" width="70" marginLeft="5" marginRight="5" />
|
||||
<Button text="Cancel" tap="onCancel" width="70" marginLeft="5" marginRight="5" />
|
||||
</StackLayout>
|
||||
|
||||
|
||||
<StackLayout orientation="horizontal" marginTop="5" marginBottom="5" horizontalAlignment="center" paddingLeft="5" paddingRight="5">>
|
||||
<Button text="Sequence" width="80" marginLeft="5" marginRight="5" tap="onSequence" />
|
||||
<Button text="Interrupted" width="80" marginLeft="5" marginRight="5" tap="onInterrupted" />
|
||||
</StackLayout>
|
||||
|
||||
</StackLayout>
|
||||
<AbsoluteLayout id="panel1" backgroundColor="Yellow" width="300" height="190" clipToBounds="true" marginTop="10">
|
||||
<Button id="button1" text="Button 1" backgroundColor="White" width="180" height="50" left="60" top="10" tap="onTap"/>
|
||||
<Button id="button2" text="Button 2" backgroundColor="White" width="180" height="50" left="60" top="70" tap="onTap"/>
|
||||
<Button id="button3" text="Button 3" backgroundColor="White" width="180" height="50" left="60" top="130" tap="onTap"/>
|
||||
<Button id="button1" text="Button 1" backgroundColor="White" width="180" height="50" left="60" top="10" tap="onTap" borderWidth="1" borderColor="red" />
|
||||
<Button id="button2" text="Button 2" backgroundColor="White" width="180" height="50" left="60" top="70" tap="onTap" borderWidth="1" borderColor="red" />
|
||||
<Button id="button3" text="Button 3" backgroundColor="White" width="180" height="50" left="60" top="130" tap="onTap" borderWidth="1" borderColor="red" />
|
||||
</AbsoluteLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
</Page>
|
@ -336,6 +336,9 @@
|
||||
"./timer/timer.ios.ts",
|
||||
"./trace/trace.d.ts",
|
||||
"./trace/trace.ts",
|
||||
"./ui/animation/animation-common.ts",
|
||||
"./ui/animation/animation.android.ts",
|
||||
"./ui/animation/animation.ios.ts",
|
||||
"./ui/activity-indicator/activity-indicator-common.ts",
|
||||
"./ui/activity-indicator/activity-indicator.android.ts",
|
||||
"./ui/activity-indicator/activity-indicator.d.ts",
|
||||
|
@ -168,59 +168,65 @@ export class Animation extends common.Animation implements definition.Animation
|
||||
}
|
||||
|
||||
trace.write("UIView.beginAnimationsContext(" + index + "): " + common.Animation._getAnimationInfo(animation), trace.categories.Animation);
|
||||
UIView.beginAnimationsContext(index.toString(), null);
|
||||
|
||||
if (animationDelegate) {
|
||||
UIView.setAnimationDelegate(animationDelegate);
|
||||
UIView.setAnimationWillStartSelector("animationWillStart");
|
||||
UIView.setAnimationDidStopSelector("animationDidStop");
|
||||
}
|
||||
UIView.animateKeyframesWithDurationDelayOptionsAnimationsCompletion(1, 0,
|
||||
UIViewKeyframeAnimationOptions.UIViewKeyframeAnimationOptionBeginFromCurrentState,
|
||||
() => {
|
||||
UIView.addKeyframeWithRelativeStartTimeRelativeDurationAnimations(0, 1, () => {
|
||||
if (animationDelegate) {
|
||||
UIView.setAnimationDelegate(animationDelegate);
|
||||
UIView.setAnimationWillStartSelector("animationWillStart");
|
||||
UIView.setAnimationDidStopSelector("animationDidStop");
|
||||
}
|
||||
|
||||
if (animation.duration !== undefined) {
|
||||
UIView.setAnimationDuration(animation.duration / 1000.0);
|
||||
}
|
||||
else {
|
||||
UIView.setAnimationDuration(0.3); //Default duration.
|
||||
}
|
||||
if (animation.delay !== undefined) {
|
||||
UIView.setAnimationDelay(animation.delay / 1000.0);
|
||||
}
|
||||
if (animation.iterations !== undefined) {
|
||||
if (animation.iterations === Number.POSITIVE_INFINITY) {
|
||||
UIView.setAnimationRepeatCount(FLT_MAX);
|
||||
}
|
||||
else {
|
||||
UIView.setAnimationRepeatCount(animation.iterations - 1);
|
||||
}
|
||||
}
|
||||
if (animation.curve !== undefined) {
|
||||
UIView.setAnimationCurve(animation.curve);
|
||||
}
|
||||
if (animation.duration !== undefined) {
|
||||
UIView.setAnimationDuration(animation.duration / 1000.0);
|
||||
}
|
||||
else {
|
||||
UIView.setAnimationDuration(0.3); //Default duration.
|
||||
}
|
||||
if (animation.delay !== undefined) {
|
||||
UIView.setAnimationDelay(animation.delay / 1000.0);
|
||||
}
|
||||
if (animation.iterations !== undefined) {
|
||||
if (animation.iterations === Number.POSITIVE_INFINITY) {
|
||||
UIView.setAnimationRepeatCount(FLT_MAX);
|
||||
}
|
||||
else {
|
||||
UIView.setAnimationRepeatCount(animation.iterations - 1);
|
||||
}
|
||||
}
|
||||
if (animation.curve !== undefined) {
|
||||
UIView.setAnimationCurve(animation.curve);
|
||||
}
|
||||
|
||||
var originalValue;
|
||||
switch (animation.property) {
|
||||
case common.Properties.opacity:
|
||||
originalValue = animation.target.opacity;
|
||||
(<any>animation)._propertyResetCallback = () => { animation.target.opacity = originalValue };
|
||||
animation.target.opacity = animation.value;
|
||||
break;
|
||||
case common.Properties.backgroundColor:
|
||||
originalValue = animation.target.backgroundColor;
|
||||
(<any>animation)._propertyResetCallback = () => { animation.target.backgroundColor = originalValue };
|
||||
animation.target.backgroundColor = animation.value;
|
||||
break;
|
||||
case _transform:
|
||||
originalValue = nativeView.transform;
|
||||
(<any>animation)._propertyResetCallback = () => { nativeView.transform = originalValue };
|
||||
nativeView.transform = Animation._createNativeAffineTransform(animation);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Cannot animate " + animation.property);
|
||||
break;
|
||||
}
|
||||
var originalValue;
|
||||
switch (animation.property) {
|
||||
case common.Properties.opacity:
|
||||
originalValue = animation.target.opacity;
|
||||
(<any>animation)._propertyResetCallback = () => { animation.target.opacity = originalValue };
|
||||
animation.target.opacity = animation.value;
|
||||
break;
|
||||
case common.Properties.backgroundColor:
|
||||
originalValue = animation.target.backgroundColor;
|
||||
(<any>animation)._propertyResetCallback = () => { animation.target.backgroundColor = originalValue };
|
||||
animation.target.backgroundColor = animation.value;
|
||||
break;
|
||||
case _transform:
|
||||
originalValue = nativeView.transform;
|
||||
(<any>animation)._propertyResetCallback = () => { nativeView.transform = originalValue };
|
||||
nativeView.transform = Animation._createNativeAffineTransform(animation);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Cannot animate " + animation.property);
|
||||
break;
|
||||
}
|
||||
})
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
trace.write("UIView.commitAnimations " + index, trace.categories.Animation);
|
||||
UIView.commitAnimations();
|
||||
|
||||
if (!playSequentially && nextAnimationCallback) {
|
||||
nextAnimationCallback();
|
||||
|
Reference in New Issue
Block a user