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
Mapbox Navigation Pod Unable to Install with Objectivec Where I am Using Xcode 9.2
How to Use Urlsession with Proxy in Swift 3
Swift: Extracting/Downcasting Cftype Based Coretext Types in a Cfarray
Wkwebview Is Showing Only Background
If Let Doesn't Unwrap Optional Value for Mkannotation's Title Property
Array Element Checking in Swift
How to Transfer Data Between Parent and Child View Controllers
Why Print() Is Printing My String as an Optional
How to Pass Values from a Pop Up View Controller to the Previous View Controller
Swift: Sort Array by Sort Descriptors
How to Update a Sent Message in Quickblox iOS
Custom Table View Row Action (Image)
How to Design an Uiscrollview in Storyboard
How Should Secure Transport Tls Be Used with Bsd Sockets in Swift
How to Insert a Override Function into a If Else Statement
Making the Map Zoom to User Location and Annotation (Swift 2)