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:
Panayot Cankov
2015-10-16 13:14:58 +03:00
4 changed files with 148 additions and 63 deletions

View File

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

View File

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

View File

@ -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",

View File

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