前提条件
我有一个动画圆,它会变成由8个贝塞尔曲线组成的形状。为了使过渡更加平滑,我需要将圆也由8个立方贝塞尔曲线组成。 这是我目前所拥有的:
代码
- (UIBezierPath*)pathBubbleLeft {
UIBezierPath *path = [UIBezierPath new];
[path moveToPoint:p(sqlx, sqlMidy)];
CGFloat r = sqlW/2;
CGFloat sin45 = 0.7071 * r;
CGFloat cos45 = 0.7071 * r;
[path addRelativeCurveToPoint:point(sqlMidx - cos45, sqlMidy - sin45) control1:vector(0, 0.4) control2:vector(0.5, 0.8)];
[path addRelativeCurveToPoint:point(sqlMidx, sqly) control1:vector(0.2, 0.5) control2:vector(0.4, 1)];
[path addRelativeCurveToPoint:point(sqlMidx + cos45, sqlMidy - sin45) control1:vector(0.6, 0) control2:vector(0.8, 0.5)];
[path addRelativeCurveToPoint:point(sqlMaxx, sqlMidy) control1:vector(0.5, 0.2) control2:vector(1, 0.5)];
[path addRelativeCurveToPoint:point(sqlMidx + cos45, sqlMidy + sin45) control1:vector(0, 0.4) control2:vector(0.5, 0.8)];
[path addRelativeCurveToPoint:point(sqlMidx, sqlMaxy) control1:vector(0.2, 0.5) control2:vector(0.4, 1)];
[path addRelativeCurveToPoint:point(sqlMidx - cos45, sqlMidy + sin45) control1:vector(0.6, 0) control2:vector(0.8, 0.5)];
[path addRelativeCurveToPoint:point(sqlx, sqlMidy) control1:vector(0.5, 0.2) control2:vector(1, 0.5)];
return path;
}
路径从左侧开始,顺时针方向绕圆周运动(从π到π / 2,0,3π / 4,π)。
point
和vector
是对CGPointMake
和CGVectorMake
的简写。
'sql'在sqlx
,sqly
,sqlMidx
,sqlMidY
,sqlMaxx
和sqlMaxy
中代表'squareLeft',即圆形的边界矩形。这些都是CGFloats。
addRelativeCurveToPoint
用于相对于起始/结束点定义控制点。(0,0)为起点,(1,1)为终点。更容易阅读。
- (void)addRelativeCurveToPoint:(CGPoint)endPoint control1:(CGVector)controlPoint1 control2:(CGVector)controlPoint2 {
CGPoint start = self.currentPoint;
CGPoint end = endPoint;
CGFloat x1 = start.x + controlPoint1.dx*(end.x - start.x);
CGFloat x2 = start.x + controlPoint2.dx*(end.x - start.x);
CGFloat y1 = start.y + controlPoint1.dy*(end.y - start.y);
CGFloat y2 = start.y + controlPoint2.dy*(end.y - start.y);
[self addCurveToPoint:endPoint controlPoint1:CGPointMake(x1, y1) controlPoint2:CGPointMake(x2, y2)];
}
迄今为止的结果如下:
![静态图片](https://istack.dev59.com/lhV3B.webp)
下图中,左边的圆使用了上述代码,右边的圆由4个曲线组成,在顶部和底部插入2个零长度插入 (
[path addLineToPoint:path.currentPoint];
)。
![输入图像描述](https://istack.dev59.com/iR6qb.gif)