Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone Core Animation - Drawing a Circle

I wish to create an animation. The best way I can explain this is if you can imagine drawing a circle. It starts at the top or 12 o clock and draws clockwise all the way around until it becomes a complete circle over the space of 10 or so seconds.

The closet I have come to this is to draw a point rotating around a center point using Core Animation (using the sample code here). But I am at a loss on how to draw the circle? Any suggestions are very welcome.

Many Thanks :)

like image 421
bennythemink Avatar asked Nov 03 '11 06:11

bennythemink


People also ask

How do you draw animation on Iphone?

Tap on the "+" icon in the top-right corner to view the objects menu. Once there, make sure you're on the "Media" tab (the fourth tab with the photos icon), then tap "Drawing" near the bottom. The drawing tools will appear and you'll see an orange header above.


2 Answers

What you really should do is to animate the stroke of a CAShapeLayer where the path is a circle. This will be accelerated using Core Animation and is less messy then to draw part of a circle in -drawRect:.

The code below will create a circle shape layer in the center of the screen and animate the stroke of it clockwise so that it looks as if it is being drawn. You can of course use any shape you'd like. (You can read this article on Ole Begemanns blog to learn more about how to animate the stroke of a shape layer.)

Note: that the stoke properties are not the same as the border properties on the layer. To change the width of the stroke you should use "lineWidth" instead of "borderWitdh" etc.

// Set up the shape of the circle int radius = 100; CAShapeLayer *circle = [CAShapeLayer layer]; // Make a circular shape circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius)                                           cornerRadius:radius].CGPath; // Center the shape in self.view circle.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,                                CGRectGetMidY(self.view.frame)-radius);  // Configure the apperence of the circle circle.fillColor = [UIColor clearColor].CGColor; circle.strokeColor = [UIColor blackColor].CGColor; circle.lineWidth = 5;  // Add to parent layer [self.view.layer addSublayer:circle];  // Configure animation CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; drawAnimation.duration            = 10.0; // "animate over 10 seconds or so.." drawAnimation.repeatCount         = 1.0;  // Animate only once..  // Animate from no part of the stroke being drawn to the entire stroke being drawn drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; drawAnimation.toValue   = [NSNumber numberWithFloat:1.0f];  // Experiment with timing to get the appearence to look the way you want drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];  // Add the animation to the circle [circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"]; 
like image 186
David Rönnqvist Avatar answered Sep 18 '22 19:09

David Rönnqvist


Here is another solution to the problem, based off @David's answer. This approach lets you set the direction of the circle's animation, and offers slightly more control. Edit: I've written a blog post on how to draw a circle with Swift, which I'll try to keep up to date with the betas. Check there if the code below doesn't work for you.

let radius = 100.0  // Create the circle layer var circle = CAShapeLayer()  // Set the center of the circle to be the center of the view let center = CGPointMake(CGRectGetMidX(self.frame) - radius, CGRectGetMidY(self.frame) - radius)  let fractionOfCircle = 3.0 / 4.0  let twoPi = 2.0 * Double(M_PI) // The starting angle is given by the fraction of the circle that the point is at, divided by 2 * Pi and less // We subtract M_PI_2 to rotate the circle 90 degrees to make it more intuitive (i.e. like a clock face with zero at the top, 1/4 at RHS, 1/2 at bottom, etc.) let startAngle = Double(fractionOfCircle) / Double(twoPi) - Double(M_PI_2) let endAngle = 0.0 - Double(M_PI_2) let clockwise: Bool = true  // `clockwise` tells the circle whether to animate in a clockwise or anti clockwise direction circle.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: clockwise).CGPath  // Configure the circle circle.fillColor = UIColor.blackColor().CGColor circle.strokeColor = UIColor.redColor().CGColor circle.lineWidth = 5  // When it gets to the end of its animation, leave it at 0% stroke filled circle.strokeEnd = 0.0  // Add the circle to the parent layer self.layer.addSublayer(circle)  // Configure the animation var drawAnimation = CABasicAnimation(keyPath: "strokeEnd") drawAnimation.repeatCount = 1.0  // Animate from the full stroke being drawn to none of the stroke being drawn drawAnimation.fromValue = NSNumber(double: fractionOfCircle) drawAnimation.toValue = NSNumber(float: 0.0)  drawAnimation.duration = 30.0  drawAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)  // Add the animation to the circle circle.addAnimation(drawAnimation, forKey: "drawCircleAnimation") 
like image 29
matthewpalmer Avatar answered Sep 18 '22 19:09

matthewpalmer