iOS的animation/变形形状从圆形到方形
我试图把一个圆圈变成一个正方形,反之亦然,我快到了。 然而它并不像预期的那样animation。 我希望广场的所有angular落都能同时进行animation/变形,但我得到的是以下内容:
我使用CAShapeLayer
和CABasicAnimation
为了animation形状属性。
以下是我如何创build圆path:
- (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; }
这是方形path:
- (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; }
我将圆形path应用到我的视图的一个图层,设置填充等,它完美绘制。 然后在我的gestureRecognizerselect器中创build并运行以下animation:
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"];
正如你可以在circlePathWithCenter:radius:
注意到的circlePathWithCenter:radius:
和squarePathWithCenter:size:
我遵循这里的build议(要有相同数量的段和控制点): Smooth shape shift animation
animation看起来更好,然后从上面的post,但它仍然不是我想要的:(
我知道我可以用简单的CALayer
做到这一点,然后设置适当的cornerRadius
级别来创build一个方形/矩形的圆形,然后在cornerRadius
属性cornerRadius
其从圆形改变为方形,但是如果它是平坦的,我仍然非常好奇可能与CAShapeLayer
和path
animation做到这CAShapeLayer
。
预先感谢您的帮助!
在操场上玩了一会之后,我注意到每条弧线在贝塞尔path上增加了两段,而不仅仅是一段。 而且,调用closePath
增加了两个。 所以为了保持细分的数量一致,我最终添加了假段到我的方形path。 代码是在Swift中,但我认为没关系。
func circlePathWithCenter(center: CGPoint, radius: CGFloat) -> UIBezierPath { let circlePath = UIBezierPath() circlePath.addArcWithCenter(center, radius: radius, startAngle: -CGFloat(M_PI), endAngle: -CGFloat(M_PI/2), clockwise: true) circlePath.addArcWithCenter(center, radius: radius, startAngle: -CGFloat(M_PI/2), endAngle: 0, clockwise: true) circlePath.addArcWithCenter(center, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI/2), clockwise: true) circlePath.addArcWithCenter(center, radius: radius, startAngle: CGFloat(M_PI/2), endAngle: CGFloat(M_PI), clockwise: true) circlePath.closePath() return circlePath } func squarePathWithCenter(center: CGPoint, side: CGFloat) -> UIBezierPath { let squarePath = UIBezierPath() let startX = center.x - side / 2 let startY = center.y - side / 2 squarePath.moveToPoint(CGPoint(x: startX, y: startY)) squarePath.addLineToPoint(squarePath.currentPoint) squarePath.addLineToPoint(CGPoint(x: startX + side, y: startY)) squarePath.addLineToPoint(squarePath.currentPoint) squarePath.addLineToPoint(CGPoint(x: startX + side, y: startY + side)) squarePath.addLineToPoint(squarePath.currentPoint) squarePath.addLineToPoint(CGPoint(x: startX, y: startY + side)) squarePath.addLineToPoint(squarePath.currentPoint) squarePath.closePath() return squarePath }
我知道这是一个古老的问题,但这可能有助于某人。
我认为它更好地生成angular落半径来获得这种效果。
let v1 = UIView(frame: CGRect(x: 100, y: 100, width: 50, height: 50)) v1.backgroundColor = UIColor.green view.addSubview(v1)
animation:
let animation = CABasicAnimation(keyPath: "cornerRadius") animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) animation.fillMode = kCAFillModeForwards animation.isRemovedOnCompletion = false animation.fromValue = v1.layer.cornerRadius animation.toValue = v1.bounds.width/2 animation.duration = 3 v1.layer.add(animation, forKey: "cornerRadius")
我可以强烈推荐库CanvasPod ,它也有一个预定义的“变形”animation,很容易整合。 您也可以在网站canvaspod.io上查看示例。
基于@Danchoys的答案,这里是Objective-C。
info是一个60px的button,infoVC是被推送的下一个ViewController:
UIBezierPath * maskPath = [UIBezierPath new]; [maskPath addArcWithCenter:info.center radius:15.0f startAngle:DEGREES_TO_RADIANS(180) endAngle:DEGREES_TO_RADIANS(270) clockwise:true]; [maskPath addArcWithCenter:info.center radius:15.0f startAngle:DEGREES_TO_RADIANS(270) endAngle:DEGREES_TO_RADIANS(0) clockwise:true]; [maskPath addArcWithCenter:info.center radius:15.0f startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(90) clockwise:true]; [maskPath addArcWithCenter:info.center radius:15.0f startAngle:DEGREES_TO_RADIANS(90) endAngle:DEGREES_TO_RADIANS(180) clockwise:true]; [maskPath closePath]; UIBezierPath * endPath = [UIBezierPath new]; [endPath moveToPoint:CGPointMake(0,0)]; [endPath addLineToPoint:endPath.currentPoint]; [endPath addLineToPoint:CGPointMake(w, 0)]; [endPath addLineToPoint:endPath.currentPoint]; [endPath addLineToPoint:CGPointMake(w, h)]; [endPath addLineToPoint:endPath.currentPoint]; [endPath addLineToPoint:CGPointMake(0, h)]; [endPath addLineToPoint:endPath.currentPoint]; [endPath closePath]; CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.frame = info.bounds; maskLayer.path = maskPath.CGPath; _infoVC.view.layer.mask = maskLayer; CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"path"]; animation.fromValue = (id)maskPath.CGPath; animation.toValue = (id)endPath.CGPath; animation.duration = 0.3f; [maskLayer addAnimation:animation forKey:nil]; [maskLayer setPath:endPath.CGPath];