0

As detailed in a previous post (Here), I'm creating an animation that starts at an initial angle and moves to an ending angle. I've decided to use CADisplayLink for this animation because the animation needs to run as fast as possible during user input, so a CALayer with a CAKeyframeAnimation seemed like it would be too slow to achieve this.

After implementing the CADisplayLink, which calls setNeedsDisplay, I do have the animation working, but it looks really bad because it chunks up the difference between endAngle and initialAngle into heavily visible blocks of angles instead of creating a continuous flow from one angle to the next. Here's the current code I have:

CGFloat newAngleToAnimate = animationProgress + ((endAngle-initialAngle)/kDrawDuration)*elapsedTime;

// Use newAngleToAnimate to draw in drawInContext

animationProgress = newAngleToAnimate; // Update the progress for the next frame.

Also, kDrawDuration is defined as 3.0f, so I want the animation from initialAngle to endAngle to take 3.0 seconds. I break up the full circle (2*M_PI radians) into equal segments by calculating 2*M_PI / kNumAnglesInAnimation, and preferably I want to animate one of those angles every frame, but somehow I still have to take kDrawDuration and elapsedTime into account, which I'm just not seeing how to achieve.

Thanks for any help with fixing this!

Community
  • 1
  • 1
J Kagney
  • 239
  • 1
  • 4
  • 9

1 Answers1

1
CGFloat newAngleToAnimate = animationProgress + ((endAngle-initialAngle)/kDrawDuration)*elapsedTime;

don't track "animationProgress". Your elapsedTime is all you need in order to get your animation correct. So just remove it and use:

CGFloat newAngleToAnimate = ((endAngle-initialAngle)/kDrawDuration)*elapsedTime;

escrafford
  • 2,373
  • 16
  • 19
  • I tried this and it doesn't animate properly. I should note that I'm using the following calculation for `elapsedTime`: `CFTimeInterval elapsedTime = _displayLink.timestamp - lastDrawTime;` Thanks, though. – J Kagney Jun 24 '13 at 17:57
  • you need to be keeping track of time since you started drawing (first draw time), not since your last draw (lastDrawTime) – escrafford Jun 24 '13 at 17:59
  • Interesting, thanks I'll try this and let you know how it works! – J Kagney Jun 24 '13 at 18:01
  • So it does work, but it still looks really "chunky" with regard to how its moving, which makes me wonder if its not related to the newAngleToAnimate calculation. If I'm dividing 2pi into say 300 different sections with the same angle between each section, is there some setting I should set on the `CADisplayLink` such as `frameInterval` in order to make it not run as fast as possible or something? – J Kagney Jun 24 '13 at 18:09
  • I think I realized what the problem is: I had the same duration for the animation no matter what the endAngle-initialAngle was. So it looks perfect when endAngle-initialAngle is less than about 2pi/3, but after that the animation duration is too short to look good for large endAngles. So I think what I'll end up doing is a switch case to set the duration for different sections of my circle. – J Kagney Jun 24 '13 at 18:20
  • Yup, I can confirm that doing CGFloat duration = 1.0*endAngleSection; where `endAngleSection` is an integer works perfectly. Thanks for all of the help! – J Kagney Jun 24 '13 at 18:25