How to animate a circle which is drawn in OpenGL? - iphone

I'm drawing several circles within my view by means of the drawRect function.
I'd like to have my circles pop up (scale to 1.2 -> scale to 1.0)
I've used coreanimation in the past but using OpenGL takes different functions.
Here's a snippit of my code which draws a circle in my view:
//calling draw function
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//setting a specific fill color
CGContextSetRGBFillColor(contextRef, 0.0, 255.0, 0.0, 1.0);
//drawing the circle with a specific height, weight and x,y location
CGContextFillEllipseInRect(contextRef, CGRectMake(30 ,30, 20,20));
How can I animate this circle that it 'pops up'.

"Pops up" is not telling me that much.
if you want it to go from small to big modify width and height of rect.use a global int variable

Related

Core Graphics Transparent Overlay

I'm replacing the background view of a UITableViewCell with my own custom subclass of UIView, in which I override the drawRect method with my own, which creates a multi-colored and changing background.
The problem is that when the TableViewCell is selected, the graphics under are completely hidden and it looks odd. I need to create a custom selectedBackgroundView in order to fix this. The problem is that that view needs to create a blue gradient tint over the graphics already there, and I don't know how to draw a CGRect or something similar that is partially transparent.
// Write this In your - (void)drawRect:(CGRect)rect
// To draw semi transparent Square
// Create Current Context To Draw
CGContextRef context = UIGraphicsGetCurrentContext();
UIBezierPath *square = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)];
// following method will fill red color with alpha 0.4 last one in parameter list
// first 3 are Red, Green and Blue Respectively.
CGContextSetRGBFillColor(context, 1, 0, 0, 0.4);
[square fill];
[square stroke];

How does CGContextTransalateCTM work?

I am trying to draw a box/path in drawRect in one of my view's, the path rect is:
CGRect pathRect = CGRectMake(self.buttonSize_ + 25, commentYOffset, rect.size.width - 80, 40);
and before this I have:
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
I wanted this path to be drawn 100 pixels from the top, so what I did is set that commentYOffset to 100, however this doesn't do it. What am I doing wrong so that when I draw this path it starts at 100 pixels from the top?
CGContextTranslateCTM(context,…) applies a translation transform to context. The translation is applied after any existing transform in the drawing context. Those last two lines in the code you posted effectively flip the vertical on your drawing context. Just leave them out and the path will be drawn where you want.
Edit: adit says he needs the transforms to keep some text drawing right side up, so: If you need to flip the vertical on your drawing context (as you're doing) then just remember that after applying these transformations zero-y is at the bottom of rect and the positive y-axis points towards the top of rect. So to draw your path 100 pixels from the top you should make
commentYOffset = CGRectGetMaxY(rect) - 40.0 - 100.0;
and that 40 is because your rect is 40 points tall. Actually it's better practice to make these named constants so you don't have to copy magic numbers all over the place going forward. Then your code will look something like this:
commentYOffset = CGRectGetMaxY(rect) - kPathRectHeight - kPathTopMargin;

Animating Circle's endAngle with CABasicAnimation

I have some UIView with drawrect code for drawing pie:
- (void)drawRect:(CGRect)rect
{
CGRect parentViewBounds = self.bounds;
CGFloat x = CGRectGetWidth(parentViewBounds)/2;
CGFloat y = CGRectGetHeight(parentViewBounds)/2;
// Get the graphics context and clear it
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextClearRect(ctx, rect);
// define line width
CGContextSetLineWidth(ctx, 4.0);
CGContextSetFillColor(ctx, CGColorGetComponents( [someColor CGColor]));
CGContextMoveToPoint(ctx, x, y);
CGContextAddArc(ctx, x, y, 100, radians(270), radians(270), 0); // 27
CGContextClosePath(ctx);
CGContextFillPath(ctx);
}
But when I try to animate "endAngle" property after drawing, it doesn't work:
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:#"endAngle"];
theAnimation.duration=1;
theAnimation.repeatCount=1;
theAnimation.autoreverses=NO;
theAnimation.fromValue=[NSNumber numberWithFloat:270];
theAnimation.toValue=[NSNumber numberWithFloat:60];
[[self.layer presentationLayer] addAnimation:theAnimation forKey:#"animateLayer"];
Where I'm making a mistake?
If you want to make an animation then you should look into using Core Animation for the drawing. It makes animation much simpler.
Have a look at this great tutorial on making a custom animatable pie chart with Core Animation. I'm sure that you can modify it to get what you want.
If it seems to complicated to you then you can have a look at my answer to "Draw part of a circle" which draws a pie chart shape by making a very wide stroke of a circle.
Several things. You can't use a CAAnimation to animate drawing that you do in a drawRect method like that.
Second, if you did use a CAShapeLayer, you could animate changes to the path that's installed in the layer, but you need to make sure that the path has the same number and type of control points for all steps in the animation.
CGPath arc commands use different numbers of control points to draw different angles. Thus, you can't change the angle of the arc and animate it.
What you have to do is to install a path that's the full length of your arc, and then animate changes to the shape layer's strokeStart and/or strokeEnd properties. Those properties cause the path to omit the first part/last part of the path from the drawing. I daresay the tutorial David linked to on the animatable pie chart uses that technique.

CGContextSetShadow produces no results

I'm using this code in my UIView subclass to draw a circle with a gradient fill:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadow (context, CGSizeMake(4,4), 5);
CGContextBeginPath (context);
CGContextAddEllipseInRect(context, CGRectMake(self.bounds.origin.x, self.bounds.origin.y, 38, 38));
CGContextClosePath (context);
CGContextClip (context);
CGContextDrawLinearGradient(context, gradient, CGPointMake(CGRectGetMinX(self.bounds), CGRectGetMaxX(self.bounds)), CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMinY(self.bounds)), 0);
}
The circle and the gradient draw fine, but I see no shadow. I'm not sure why its not working, because I used the same CGContextSetShadow function in a different view subclass and it worked fine.
NOTE: In the above code, "gradient" is an ivar that was defined previously.
A gradient draw doesn't count as a fill; only fills and strokes get shadows. (You may want to report this as a bug.)
As a workaround, fill the path (with solid black), then turn off the shadow, then draw the gradient.

how to draw on the surface of imageview transparently

i want to track finger touch and draw the path on top of the imageView.
following is what i did:
In the touch event:
UIgraphicsBeginImageContext(imageView.frame.size);
[imageView.image drawInRect:CGRectMake(0,0,imageView.size.width,imageView.size.height)];
//drawing.....
imageView.image=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
however, the drawing opaque the background Image?
how to drawing the path while still can make the background available?
thanks in advance:)
If you're doing simple vector drawing, you can set a color with a non-1.0 alpha value. These shapes will then be translucent when you draw them on top of your image. For example:
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGFloat values[4] = {1.0, 0.0, 0.0, 0.5};
CGColorRef translucentRed = CGColorCreate(space, values);
CGContextSetStrokeColorWithColor(context, translucentRed);
CGContextSetFillColorWithColor(context, translucentRed)
// Do your drawing here
CGColorRelease(translucentRed);
CGColorSpaceRelease(space);
will create a translucent red color and set the current stroke and fill to use that color.
Note that overlapping drawn elements will have darker areas because of this translucency, which might be an effect that you don't want.