Changing CALayer speed in CABasicAnimation as the wheel rotates causes a jerking effect

I am developing an application that requires the wheel to rotate around the z axis with increasing or decreasing wheel speed over time. I am using CABasicAnimation and my code is as follows. While I change the layer speed property at a certain interval, it causes a β€œtrembling” wheel effect.

/ **** /

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 the timer, I change the speed of the CALayer image as shown below: dPlayedPercentage is a variable.

 imageLeft.layer.speed=1.0+dPlayedPercentage; [imageLeft.layer addAnimation:animation forKey:@"SpinAnimation"]; 

I think this is due to a position reset when changing the CALayer speed property. What should I do to fix this. Or any other way to make this animation?

+4
source share
2 answers

Adding the following code eliminates the push in the animation.

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

For a more dynamic change in speed, I have a problem with the previous answer (the layer is not drawn at all), since timeOffset had to be calculated taking into account the new speed.

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

The basic formula for timeOffset :
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 
0
source

Source: https://habr.com/ru/post/1487889/


All Articles