实现思路
图解动画都三部分组成:小圆,大圆,不规整连线;小圆和大圆非常容易实现,我们重点需要考虑的是中间的不规整连接怎么处理。
思考思考继续思考。。。叮咚。。。贝塞尔曲线
AB直线+BPC二次曲线+CD直线+DOA二次曲线,这样我们就组成了一个全包围的不规整图形。
接下来的任务就是对坐标点的计算,使用简单的三角函数就能得出每个点的具体坐标。
O点和P点是两个圆切线的交点,坐标位置有我们自己定。控制曲率。
具体计算看图,代码计算部分是不是看得眼睛很累,只需要注意O点和P点,小于d值可以确保点在内侧,demo使用的d/2。其它点ABCD都可以很轻松算出来。再关注下贝塞尔曲线的绘制部分,这个工具就实现了90%了。剩下的看Demo.
- (UIBezierPath *)pathWithBigCirCleView:(UIView *)bigCirCleView smallCirCleView:(UIView *)smallCirCleView
{
CGPoint bigCenter = bigCirCleView.center;
CGFloat x2 = bigCenter.x;
CGFloat y2 = bigCenter.y;
CGFloat r2 = bigCirCleView.bounds.size.width / 2;
CGPoint smallCenter = smallCirCleView.center;
CGFloat x1 = smallCenter.x;
CGFloat y1 = smallCenter.y;
CGFloat r1 = smallCirCleView.bounds.size.width / 2;
// 获取圆心距离
CGFloat d = [self pointToPintDistanceWithAPoint:self.smallCircleView.center bPoint:self.center];
CGFloat sinθ = (x2 - x1) / d;
CGFloat cosθ = (y2 - y1) / d;
// 坐标系基于父控件
CGPoint pointA = CGPointMake(x1 - r1 * cosθ , y1 + r1 * sinθ);
CGPoint pointB = CGPointMake(x1 + r1 * cosθ , y1 - r1 * sinθ);
CGPoint pointC = CGPointMake(x2 + r2 * cosθ , y2 - r2 * sinθ);
CGPoint pointD = CGPointMake(x2 - r2 * cosθ , y2 + r2 * sinθ);
CGPoint pointO = CGPointMake(pointA.x + d / 2 * sinθ , pointA.y + d / 2 * cosθ); //AO距离越短,OD切角越小,OD越直;AO距离越大,AO切角越小,AO越直
CGPoint pointP = CGPointMake(pointB.x + d / 2 * sinθ , pointB.y + d / 2 * cosθ);
UIBezierPath *path = [UIBezierPath bezierPath];
// A
[path moveToPoint:pointA];
// AB
[path addLineToPoint:pointB];
// 绘制BC曲线
[path addQuadCurveToPoint:pointC controlPoint:pointP];
// CD
[path addLineToPoint:pointD];
// 绘制DA曲线
[path addQuadCurveToPoint:pointA controlPoint:pointO];
return path;
}
网友评论