Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animation CAShapeLayer

I draw a graph with this code:

CAShapeLayer *curentGraph = [CAShapeLayer new];
CGMutablePathRef linePath = CGPathCreateMutable();
curentGraph.lineWidth = 3.0f;
curentGraph.fillColor = [[UIColor clearColor] CGColor];
curentGraph.strokeColor = [colorGraph CGColor];
for (NSValue *value in arrOfPoints) {
    CGPoint pt = [value CGPointValue];
    CGPathAddLineToPoint(linePath, NULL, pt.x,pt.y);
};
curentGraph.path = linePath;CGPathRelease(linePath);
[self.layer addSublayer:curentGraph];

and it looks like this

screenshot of graph

But I have a problem. I need to animate the graph as it appears. Every point should move up from position y = 0 to y = pt.y. Like they do in the graph on this site.

How do I animate my graph like that?

like image 938
Max Sim Avatar asked Dec 06 '25 05:12

Max Sim


2 Answers

Here is a CAShapeLayer subclass that'll allow you to animate its path implicitly (without having to declare a CABasicAnimation):

Interface:

@interface CAShapeLayerAnim : CAShapeLayer
@end

Implementation:

@implementation CAShapeLayerAnim

- (id<CAAction>)actionForKey:(NSString *)event {
    if ([event isEqualToString:@"path"]) {
        CABasicAnimation *animation = [CABasicAnimation
            animationWithKeyPath:event];
        animation.duration = [CATransaction animationDuration];
        animation.timingFunction = [CATransaction
            animationTimingFunction];
        return animation;
    }
   return [super actionForKey:event];
}

@end
like image 123
Cyrille Avatar answered Dec 07 '25 20:12

Cyrille


The path property on CAShapeLayer is animatable. This means that you can create one path where every y value is 0.0 and the animate from that path to the real graph. Just make sure that the paths have the same number of points. This should be easy, since you already have the loop.

CGMutablePathRef startPath = CGPathCreateMutable();
for (NSValue *value in arrOfPoints) {
    CGPoint pt = [value CGPointValue];
    CGPathAddLineToPoint(startPath, NULL, pt.x, 0.0);
}

Then you can animate the path by creation a CABasicAnimation for the @"path" key.

CABasicAnimation *pathAppear = [CABasicAnimation animationWithKeyPath:@"path"];
pathAppear.duration = 2.0; // 2 seconds
pathAppear.fromValue = (__bridge id)startPath;
pathAppear.toValue   = (__bridge id)linePath;

[yourShapeLayer addAnimation:pathAppear forKey:@"make the path appear"];
like image 28
David Rönnqvist Avatar answered Dec 07 '25 22:12

David Rönnqvist