Animating CAShapeLayer with moving frame
Using core animation layers, I've been trying to implement the following feature. Within a containing superlayer, there are two anchor layers, and another layer that connects the two. The following image should make the situation clear. On the left, the two orange-coloured anchors are marked 'A' and 'B', and the green line connects them. The enclosing layer frames are shown using dotted lines. On the right, the layer hierarchy is shown as I've currently implemented it, where both the anchors and the connection are sublayer of the enclosing superlayer.
Now, what I'm trying to do is allow the anchors to be moved around, and have the connection stay attached. I'm currently updating its frame and path properties exploiting the connection layer's -setFrame:
method , using the code shown below:
- (void)setFrame:(CGRect)frame {
CGSize size = frame.size;
CGPoint startPoint = CGPointZero;
if (size.height < 0.0) startPoint.y -= size.height;
CGPathRef oldPath = self.path;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, startPoint.x, startPoint.y);
CGPathAddLineToPoint(path, NULL, startPoint.x + size.width, startPoint.y + size.height);
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = [CATransaction animationDuration];
animation.timingFunction = [CATransactio开发者_JAVA技巧n animationTimingFunction];
animation.fromValue = (id)oldPath;
animation.toValue = (id)path;
[self addAnimation:animation forKey:@"pathAnimation"];
self.path = path;
CGPathRelease(path);
[super setFrame:frame];
}
Now, this sort of works, but the problem is that the frame (or position + bounds) animation doesn't run in sync with the path animation, causing some jittery effects where the connection's far end momentarily detaches (and some other minor issues to, presumably caused by the same core issue).
I've been toying around with the issue, but only to moderate success. At one point, I set the connection's frame equal to that of the enclosing superlayer, which did have the desired effect (since now the frame doesn't need to be animated any longer). However, I'm worried about the performance of this solution in a context with multiple connections—ie. multiple non-opaque, large-size overlapping layers seems bad?
Would anyone have a better, more elegant solution to this? Thanks!
Since you're only really stretching (scaling) and rotating the connection layer have you considered applying transformations to it instead of manually modifying the frame?
You should be able to calculate the angle of rotation and scaling factor using some basic trigonometry based on the positions of the anchor layers.
Since you are animating the path and not the frame of the layer or path, you will get performance issues after approx. 50 simultaneous animations. You will achieve high performance only when manipulating the layers implicit animatable properties, therefore its frame and not its content (e.g path), because of gpu acceleration.
精彩评论