iOS动画/变形形状从圆到正方形

fge*_*iew 12 animation calayer cabasicanimation cashapelayer ios

我尝试将圆圈变成正方形,反之亦然,我几乎就在那里.然而,它没有像预期的那样动画.我想在一个正方形的所有角落同时进行动画/变形,但我得到的是以下内容:

在此输入图像描述

我使用CAShapeLayerCABasicAnimation为动画形状属性.

以下是我创建圆路径的方法:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

这是方形路径:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

我将圆形路径应用到我的一个View图层,设置填充等.它完美地绘制.然后在我的gestureRecognizer选择器中创建并运行以下动画:

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"];
Run Code Online (Sandbox Code Playgroud)

正如你可以注意到的那样circlePathWithCenter:radius:,squarePathWithCenter:size:我按照这里的建议(具有相同数量的段和控制点): 平滑的形状移动动画

动画看起来比从上面的帖子好,但它仍然不是我想要实现的那个:(

我知道我可以用简单的方法做到这一点,CALayer然后设置适当的水平cornerRadius来制作一个方形/矩形的圆形,然后在那个有生命的cornerRadius属性之后将它从圆形变为方形但是如果它甚至可以做的话我仍然非常好奇它CAShapeLayerpath动画.

在此先感谢您的帮助!

Dan*_*oys 8

在操场上玩了一会儿之后,我注意到每个弧线都会向贝塞尔曲线路径添加两个线段,而不仅仅是一个.此外,呼叫closePath还增加了两个.因此,为了保持段的数量一致,我最终在我的方路径中添加了假段.代码在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
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


ila*_*lan 6

我知道这是一个老问题,但这可能对某人有所帮助。

我认为最好为圆角半径设置动画以获得这种效果。

    let v1 = UIView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
    v1.backgroundColor = UIColor.green
    view.addSubview(v1)
Run Code Online (Sandbox Code Playgroud)

动画片:

    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")
Run Code Online (Sandbox Code Playgroud)