开发者

What's the easiest way to animate a line?

I am creating an app that involves animating lines within a workspace over time. My current approach for this is to use code like this in drawRect:

CGContextSetStrokeColor(context, black);
CGContextBeginPath(context);
CGContextMoveToPoint(context, startPoint.x, startPoint.y);
CGContextAddLineToPoint(context, finalPoint.x, finalPoint.y);
CGContextStrokePath(context);

...and then just setting a timer to run every 0.05 seconds to update finalPoint and call setNeedsDisplay.

I'm finding this approach (when there's 5ish lines moving at once) slows down the app terribly, and even with such a high refresh frequency, still appears jerky.

There must be some better way to perform this very simple line drawing in an animated line - i.e. saying that I want a line to start at x1, y1 and stretching to x2, y2 over a given length of time. What are m开发者_如何转开发y options for this? I need to make this perform faster and would love to get rid of this clunky timer.

Thanks!


Use CAShapeLayers, and a combination of CATransactions and CABasicAnimation.

You can add a given path to a shapeLayer and let it do the rendering.

A CAShapeLayer object has two properties called strokeStart and strokeEnd, which defines where along the path the end of the line should render. The defaults are 0.0 for strokeStart, and 1.0 for strokeEnd.

If you set up your path so that strokeEnd initially starts at 0.0, you will see no line.

You can then animate, from 0.0 to 1.0, the strokeEnd property and you will see the line lengthen.

To change CAShapeLayer's implicit 0.25s default animation timing, you can add a function to the class, like so:

-(void)animateStrokeEnd:(CGFloat)_strokeEnd {
    [CATransaction begin];
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath];
    animation.duration = 2.0f; //or however long you want it to happen
    animation.fromValue = [NSNumber numberWithFloat:self.strokeEnd]; // from the current strokeEnd value
    animation.toValue = [NSNumber numberWithFloat:_strokeEnd]; //to the end of the path
    [CATransaction setCompletionBlock:^{ self.strokeEnd = _strokeEnd }];
    [self addAnimation:animation forKey:@"animateStrokeEnd"];
    [CATransaction commit];
}

You can pass any value from 0.0f to 1.0f as the value of _strokeEnd.

The setCompletionBlock: ensures that the value you are passing is explicitly set after the animation completes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜