Change Duration (Speed) on a Running Animation

Change duration (speed) on a running animation

After a long struggle I came up with a solution that seems to work perfectly and give a smooth transition between animations. Basically I just figure out the current angle of rotation and use it to restart the animation at a different rate. One critical point here is in the last line: you MUST have that anim.keyPath there - it can't be Nil (as learned from experience). That way the new animation replaces the old animation, I guess. Oh, and to make it more clear: symmetryAngle is a rotation that makes the object look the same, like 72 degrees for 5-fold symmetry.

-(void)startWheelsAnimation:(float)deltaT
{
float startingAngle = 0.0;

if(isAnimating) {
// If animation is in progress then calculate startingAngle to
// reflect the current angle of rotation
CALayer *presLayer = (CALayer*)[blobView.layer presentationLayer];
CATransform3D transform = [presLayer transform];
startingAngle = atan2(transform.m12, transform.m11);
}

isAnimating = YES;

// Restart the animation with different duration, and so that it starts
// from the current angle of rotation
CABasicAnimation * anim = [ CABasicAnimation animationWithKeyPath:@"transform.rotation.z" ] ;
anim.duration = deltaT;
anim.repeatCount = CGFLOAT_MAX;
anim.fromValue = @(startingAngle);
anim.toValue = @(startingAngle - symmetryAngle) ;
[blobView.layer addAnimation:anim forKey:anim.keyPath];
}

How to change animation speed when is playing?

You can use Interpolators to have a variable speed during animation. Example can be found here.

How to change AnimationTimer speed?

The AnimationTimer's handle method is invoked once for each frame that is rendered, on the FX Application Thread. You should never block that thread, so do not call Thread.sleep(...) here.

The parameter passed to the handle(...) method is a timestamp, in nanoseconds. So if you want to throttle updates so they don't happen more than once every, say 28 milliseconds, you can use this to do so:

private void initialize() {
programButtonAnimation=new AnimationTimer(){

private long lastUpdate = 0 ;
@Override
public void handle(long now) {
if (now - lastUpdate >= 28_000_000) {
showClockAnimation();
lastUpdate = now ;
}
}
};
programButtonAnimation.start();
}

private void showClockAnimation(){
String imageName = "%s_"+"%05d"+".%s";
String picturePath="t093760/diploma/view/styles/images/pink_frames/"+String.format( imageName,"pink" ,frameCount,"png");
programButton.setStyle("-fx-background-image:url('"+picturePath+"')");
frameCount++;
if(frameCount>=120){
programButtonAnimation.stop();
frameCount=0;
}
}

How do you speed up an animation mid animation with jQuery?

You can use the step option of animate to keep track of how far along the animation is. Then with that information, you can calculate the time remaining in the animation. Then stop the current animation and start a new one with half the duration.

http://jsfiddle.net/MdD45/

EDIT

It looks like the 2nd parameter passed to step contains a property named pos which tells you what percentage along in the animation you are. That can simplify things further.

http://jsfiddle.net/MdD45/1/

var startVal = 0;
var endVal = 1;
var duration = 10000;

var howfar = 0;

$('span').css("opacity",startVal)
.animate({
opacity : endVal
}, {
duration: duration,
step: function(now, fx){
howfar = fx.pos; // between 0 and 1, tells how far along %
}
});

$("button").click(function(){
// calculate the new duration as half of the remaining duration
var timeRemaining = duration - (howfar * duration);
duration = timeRemaining / 2;

$('span').stop().animate({
opacity : endVal
}, {
duration: duration,
step: function(now, fx){
howfar = fx.pos; // between 0 and 1, tells how far along %
}
});
});

Change jQuery's animation duration during animating

The duration is passed by value, not by reference. So animate does not store a reference to duration. Even if you update the options object (which is passed by reference) jQuery uses options.duration internally, which means it will be passed by value.

As a quick fix you could stop the animation and restart it with the new duration - adjusting for the part of the animation that is already over.

You'd need to consider how you want it to behave, for example when you speed up a 4 second animation to a 2 second animation after 3 seconds. In the code below the animation will be immediate. Thinking about it, that's probably not what you want since you probably really care about speed, not duration.

The code below is a rough sketch, I'm not sure if it's accurate, if it works when decreasing animation values or how it handles multiple animation values. You can also only change the duration once.

var state = false,
duration = 8000;

$(document).click(function (e) {
state = true;
duration = 1000;
});
var animationCss = {top:200, left:200};
$('#foo').animate(animationCss, {
duration: duration,
step: function(now, fx){
if(state) {
$("#foo").stop();
var percentageDone = (fx.now - fx.start) / (fx.end - fx.start)
var durationDone = fx.options.duration * percentageDone;
var newDuration = duration - durationDone;
if (newDuration < 0)
{
newDuration = 0;
}
$("#foo").animate(animationCss, { duration: newDuration})

}
}
});

http://fiddle.jshell.net/5cdwc/3/



Related Topics



Leave a reply



Submit