CAShapelayer 如何通过动画从圆形转换为方形(反之亦然)?
How CAShapelayer transform from circle to square (or vice versa) with animation?
CAShapelayer
如何使用 CABasicAnimation
从圆形变为方形(反之亦然)?
你可以玩 cornerRadius
。例如,
UIView *testView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 50, 50)];
CAShapeLayer *layer = [[CAShapeLayer alloc]initWithLayer:testView.layer]; // this is square layer
layer.cornerRadius = 25.0; // this is round layer
layer.cornerRadius = 0.0; // this is again square layer
您可以像上面的方法一样直接将视图从圆形切换到方形,从方形切换到圆形!
这里是创建圆的路径:
- (UIBezierPath *)circlePathWithCenter:(CGPoint)center radius:(CGFloat)radius
{
UIBezierPath *circlePath = [UIBezierPath bezierPath];
[circlePath addArcWithCenter:center radius:radius startAngle:0 endAngle:M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI/2 endAngle:M_PI clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI endAngle:3*M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:3*M_PI/2 endAngle:M_PI clockwise:YES];
[circlePath closePath];
return circlePath;
}
这是方形路径:
- (UIBezierPath *)squarePathWithCenter:(CGPoint)center size:(CGFloat)size
{
CGFloat startX = center.x-size/2;
CGFloat startY = center.y-size/2;
UIBezierPath *squarePath = [UIBezierPath bezierPath];
[squarePath moveToPoint:CGPointMake(startX, startY)];
[squarePath addLineToPoint:CGPointMake(startX+size, startY)];
[squarePath addLineToPoint:CGPointMake(startX+size, startY+size)];
[squarePath addLineToPoint:CGPointMake(startX, startY+size)];
[squarePath closePath];
return squarePath;
}
动画部分
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.fromValue = (__bridge id)(self.stateLayer.path);
animation.toValue = (__bridge id)(self.stopPath.CGPath);
self.stateLayer.path = self.stopPath.CGPath;
[self.stateLayer addAnimation:animation forKey:@"animatePath"];
在做了一些变通之后,我就这样结束了
首先为方形和圆形路径以及 CAShapeLayer
对象制作 UIBezierPath
的全局对象。
@implementation Demo{
CAShapeLayer *shapeLayer;
UIBezierPath *sqPath;
UIBezierPath *crclePath;
}
现在,自定义您的 shapeLayer
并添加到下面 viewDidLoad
中的图层。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = [[UIColor redColor] CGColor];
shapeLayer.lineWidth = 2;
shapeLayer.lineJoin = kCALineCapRound;
sqPath = [self makeSquare:self.view.center squareWidth:200];
shapeLayer.path = [sqPath CGPath];
crclePath = [self makeCircle:self.view.center radius:100];
[self.view.layer addSublayer:shapeLayer];
}
下面是制作完美正方形的方法
-(UIBezierPath*)makeSquare:(CGPoint)centrePoint squareWidth:(float)gain{
float x=centrePoint.x-(gain/2);
float y=centrePoint.y-(gain/2);
UIBezierPath *apath = [UIBezierPath bezierPath];
[apath moveToPoint:CGPointMake(x,y)];
[apath addLineToPoint:apath.currentPoint];
[apath addLineToPoint:CGPointMake(x+gain,y)];
[apath addLineToPoint:apath.currentPoint];
[apath addLineToPoint:CGPointMake(x+gain,y+gain)];
[apath addLineToPoint:apath.currentPoint];
[apath addLineToPoint:CGPointMake(x,y+gain)];
[apath addLineToPoint:apath.currentPoint];
[apath closePath];
return apath;
}
下面是制作圆圈的方法
- (UIBezierPath *)makeCircle:(CGPoint)center radius:(CGFloat)radius
{
UIBezierPath *circlePath = [UIBezierPath bezierPath];
[circlePath addArcWithCenter:center radius:radius startAngle:-M_PI endAngle:-M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:-M_PI/2 endAngle:0 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:0 endAngle:M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI/2 endAngle:M_PI clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI endAngle:-M_PI clockwise:YES];
[circlePath closePath];
return circlePath;
}
最后,在 btnDone
的动作中完成动画,它使用 CABasicAnimation
动画从方形到圆形的转换,反之亦然。
- (IBAction)btnDone:(id)sender {
btnDowrk.selected=!btnDowrk.selected;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
if (btnDowrk.selected) {
animation.fromValue = (__bridge id)(sqPath.CGPath);
animation.toValue = (__bridge id)(crclePath.CGPath);
shapeLayer.path = crclePath.CGPath;
}
else{
animation.fromValue = (__bridge id)(crclePath.CGPath);
animation.toValue = (__bridge id)(sqPath.CGPath);
shapeLayer.path = sqPath.CGPath;
}
[shapeLayer addAnimation:animation forKey:@"animatePath"];
}
CAShapelayer
如何使用 CABasicAnimation
从圆形变为方形(反之亦然)?
你可以玩 cornerRadius
。例如,
UIView *testView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 50, 50)];
CAShapeLayer *layer = [[CAShapeLayer alloc]initWithLayer:testView.layer]; // this is square layer
layer.cornerRadius = 25.0; // this is round layer
layer.cornerRadius = 0.0; // this is again square layer
您可以像上面的方法一样直接将视图从圆形切换到方形,从方形切换到圆形!
这里是创建圆的路径:
- (UIBezierPath *)circlePathWithCenter:(CGPoint)center radius:(CGFloat)radius
{
UIBezierPath *circlePath = [UIBezierPath bezierPath];
[circlePath addArcWithCenter:center radius:radius startAngle:0 endAngle:M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI/2 endAngle:M_PI clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI endAngle:3*M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:3*M_PI/2 endAngle:M_PI clockwise:YES];
[circlePath closePath];
return circlePath;
}
这是方形路径:
- (UIBezierPath *)squarePathWithCenter:(CGPoint)center size:(CGFloat)size
{
CGFloat startX = center.x-size/2;
CGFloat startY = center.y-size/2;
UIBezierPath *squarePath = [UIBezierPath bezierPath];
[squarePath moveToPoint:CGPointMake(startX, startY)];
[squarePath addLineToPoint:CGPointMake(startX+size, startY)];
[squarePath addLineToPoint:CGPointMake(startX+size, startY+size)];
[squarePath addLineToPoint:CGPointMake(startX, startY+size)];
[squarePath closePath];
return squarePath;
}
动画部分
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.fromValue = (__bridge id)(self.stateLayer.path);
animation.toValue = (__bridge id)(self.stopPath.CGPath);
self.stateLayer.path = self.stopPath.CGPath;
[self.stateLayer addAnimation:animation forKey:@"animatePath"];
在做了一些变通之后,我就这样结束了
首先为方形和圆形路径以及 CAShapeLayer
对象制作 UIBezierPath
的全局对象。
@implementation Demo{
CAShapeLayer *shapeLayer;
UIBezierPath *sqPath;
UIBezierPath *crclePath;
}
现在,自定义您的 shapeLayer
并添加到下面 viewDidLoad
中的图层。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = [[UIColor redColor] CGColor];
shapeLayer.lineWidth = 2;
shapeLayer.lineJoin = kCALineCapRound;
sqPath = [self makeSquare:self.view.center squareWidth:200];
shapeLayer.path = [sqPath CGPath];
crclePath = [self makeCircle:self.view.center radius:100];
[self.view.layer addSublayer:shapeLayer];
}
下面是制作完美正方形的方法
-(UIBezierPath*)makeSquare:(CGPoint)centrePoint squareWidth:(float)gain{
float x=centrePoint.x-(gain/2);
float y=centrePoint.y-(gain/2);
UIBezierPath *apath = [UIBezierPath bezierPath];
[apath moveToPoint:CGPointMake(x,y)];
[apath addLineToPoint:apath.currentPoint];
[apath addLineToPoint:CGPointMake(x+gain,y)];
[apath addLineToPoint:apath.currentPoint];
[apath addLineToPoint:CGPointMake(x+gain,y+gain)];
[apath addLineToPoint:apath.currentPoint];
[apath addLineToPoint:CGPointMake(x,y+gain)];
[apath addLineToPoint:apath.currentPoint];
[apath closePath];
return apath;
}
下面是制作圆圈的方法
- (UIBezierPath *)makeCircle:(CGPoint)center radius:(CGFloat)radius
{
UIBezierPath *circlePath = [UIBezierPath bezierPath];
[circlePath addArcWithCenter:center radius:radius startAngle:-M_PI endAngle:-M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:-M_PI/2 endAngle:0 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:0 endAngle:M_PI/2 clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI/2 endAngle:M_PI clockwise:YES];
[circlePath addArcWithCenter:center radius:radius startAngle:M_PI endAngle:-M_PI clockwise:YES];
[circlePath closePath];
return circlePath;
}
最后,在 btnDone
的动作中完成动画,它使用 CABasicAnimation
动画从方形到圆形的转换,反之亦然。
- (IBAction)btnDone:(id)sender {
btnDowrk.selected=!btnDowrk.selected;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
if (btnDowrk.selected) {
animation.fromValue = (__bridge id)(sqPath.CGPath);
animation.toValue = (__bridge id)(crclePath.CGPath);
shapeLayer.path = crclePath.CGPath;
}
else{
animation.fromValue = (__bridge id)(crclePath.CGPath);
animation.toValue = (__bridge id)(sqPath.CGPath);
shapeLayer.path = sqPath.CGPath;
}
[shapeLayer addAnimation:animation forKey:@"animatePath"];
}