Question

I develop an app which requires a wheel to be rotated around z axis with increasing or decreasing the speed of the wheel steadily over time. I use CABasicAnimation & my code is as follows. While i change the speed property of the layer at particular interval, it causes "Jerk" effect to the wheel.

/****/

CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.toValue = [NSNumber numberWithFloat:-2*M_PI];
animation.duration = 4.0f;
animation.repeatCount = INFINITY;
[animation setValue:@"left" forKey:@"side"];
[animation setDelegate:self];
animation.removedOnCompletion=NO;
animation.fillMode = kCAFillModeForwards;
animation.cumulative = YES;

imageLeft.layer.beginTime = CACurrentMediaTime();
/************/

In a timer I vary the speed of the CALayer of the imageview as follows where dPlayedPercentage is a variable.

imageLeft.layer.speed=1.0+dPlayedPercentage;

[imageLeft.layer addAnimation:animation forKey:@"SpinAnimation"];

I think it is due to the position resets while changing the speed property of CALayer. What should i do to rectify this. Or any other way to do this animation?

Was it helpful?

Solution

Adding the following code has rectified the jerk in the animation.

imageLeft.layer.timeOffset = [imageLeft.layer convertTime:CACurrentMediaTime() fromLayer:nil]; 
imageLeft.layer.beginTime = CACurrentMediaTime(); 
imageLeft.layer.speed=1.0+dPlayedPercentage;

OTHER TIPS

For more dynamic speed change, I has some issue with the previous answer (layer not drawing at all) since the timeOffset needed to be calculated with the new speed in mind.

(source https://coveller.com/2016/05/core_animation_timing)

The base formula for the timeOffset is:
timeOffset = CACurrentMediaTime() - ((convertTime - beginTime) x speed)

In code:

theLayer.speed = newSpeed

let mediaTime = CACurrentMediaTime()

let converedTime = theLayer.convertTime(mediaTime, to: nil)

theLayer.beginTime = mediaTime

let offset = mediaTime - ((converedTime - theLayer.beginTime) * Double(newSpeed))

theLayer.timeOffset = offset
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top