阅读 99

UIBezierPath

贝塞尔曲线

贝塞尔曲线,又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的

下面分别是 一阶、二阶、三阶、高阶 曲线图image.gif

image.gif

image.gif

image.gif

贝塞尔曲线的应用

贝塞尔曲线在iOS中有一个对应的类,叫做UIBezierPathUIBezierPathCore Graphics框架关于路径的封装

UIBezierPath通常与CAShapeLayer配合使用。CAShapeLayer继承自CALayer,它拥有CALayer的所有属性。UIBezierPathCAShapeLayer提供路径, CAShapeLayer在提供的路径中进行渲染, 绘制出图形

属性介绍

  • CGPath:将UIBezierPath类转换成CGPath,类似于UIColor的CGColor

  • empty:只读类型,路径上是否有有效的元素

  • bounds:和view的bounds是不一样的,它获取path的X坐标、Y坐标、宽度,但是高度为0

  • currentPoint:当前path的位置,可以理解为path的终点

  • lineWidth:path宽度

  • lineCapStyle:path端点样式,有3种样式

image.png

  • lineJoinStyle:拐角样式

image.png

  • miterLimit:最大斜接长度(只有在使用kCGLineJoinMiter是才有效), 边角的角度越小,斜接长度就会越大

image.png

为了避免斜接长度过长,使用lineLimit属性限制,如果斜接长度超过miterLimit,边角就会以KCALineJoinBevel类型来显示

image.png

  • flatness:弯曲路径的渲染精度,默认为0.6,越小精度越高,相应的更加消耗性能。

  • usesEvenOddFillRule:单双数圈规则是否用于绘制路径,默认是NO。

- UIRectCorner:角

  • 创建在rect内的矩形:

    • (instancetype)bezierPathWithRect:(CGRect)rect:

  • 创建在rect里的内切曲线:

    • (instancetype)bezierPathWithOvalInRect:(CGRect)rect:

  • 创建带有圆角的矩形,当矩形变成正圆的时候,Radius就不再起作用:

  + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius

  • 设定特定的角为圆角的矩形:

    • (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii

  • 创建圆弧

    • (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise

  • 通过已有路径创建路径:

    UIBezierPath *path_A = [UIBezierPath bezierPath];
    [path_A moveToPoint:CGPointMake(200, 50)];
    [path_A addLineToPoint:CGPointMake(250, 100)];
    path_A.lineWidth = 5.0f;
    UIBezierPath *path_B = [UIBezierPath bezierPathWithCGPath:path_A.CGPath];
    [path_B stroke];复制代码
  • 创建二次贝塞尔曲线

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(200, 300)];
    [path addQuadCurveToPoint:endPoint controlPoint:controlPoint];
    [path stroke];复制代码
  • 创建三次贝塞尔曲线

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(200, 200)];
    [path addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
    [path stroke];复制代码
  • 添加圆弧

/**
 *  添加圆弧
 *  @param center     圆点
 *  @param radius     半径
 *  @param startAngle 起始位置
 *  @param endAngle   结束为止
 *  @param clockwise  是否顺时针方向
 */
- (void)createAddArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise{

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(200, 400)];
    [path addLineToPoint:CGPointMake(225, 410)];
    [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:clockwise];
    [path closePath];
    [path removeAllPoints];
    [path stroke];
}复制代码
  • 追加路径

/**
 *  追加路径
 */
- (void)appendPath{
    UIBezierPath *path_A = [UIBezierPath bezierPath];
    [path_A moveToPoint:CGPointMake(200, 500)];
    [path_A addLineToPoint:CGPointMake(225, 410)];
    UIBezierPath *path_B = [UIBezierPath bezierPath];
    [path_B moveToPoint:CGPointMake(200, 600)];
    [path_B addLineToPoint:CGPointMake(225, 500)];
    [path_A appendPath:path_B];
    [path_A stroke];

}复制代码
  • 创建翻转路径,即起点变成终点,终点变成起点

- (void)createReversingPath{
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(50, 50)];
    [path addLineToPoint:CGPointMake(100, 50)];
    path.lineWidth = 5.0f;
    NSLog(@"%@",NSStringFromCGPoint(path.currentPoint));
    UIBezierPath *path_b = [path bezierPathByReversingPath];
    NSLog(@"%@",NSStringFromCGPoint(path_b.currentPoint));
    [path_b stroke];
}复制代码
  • 路径进行仿射变换

- (void)createApplyTransform{

    CGAffineTransform transform = CGAffineTransformMakeScale(2, 2);
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(10, 50)];
    [path addLineToPoint:CGPointMake(100, 50)];
    [path applyTransform:transform];
    path.lineWidth = 5.0f;
    [path stroke];
}复制代码
  • 创建虚线

/**
 *  创建虚线
 *  @param pattern C类型线性数据
 *  @param count   pattern中数据个数
 *  @param phase   起始位置
 */

- (void)createLineDash:(nullable const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase{
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(50, 50)];
    [path addLineToPoint:CGPointMake(100, 50)];
    [path setLineDash:pattern count:count phase:0.0];
    [path stroke];

}复制代码
  • 设置颜色

- (void)setLineColor:(UIColor *)lineColor fillColor:(UIColor *)fillColor{
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
    [lineColor setStroke];
    [fillColor setFill];
    [path stroke];
    [path fill];

}复制代码
  • 设置描边混合模式

- (void)setFillWithBlendMode{
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
    [[UIColor redColor] setFill];
    [path fillWithBlendMode:kCGBlendModeSaturation alpha:0.6];
    [path fill];

}

- (void)setStrokeWithBlendMode{

    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
    [[UIColor greenColor] setStroke];
    path.lineWidth = 10.0f;
    [path strokeWithBlendMode:kCGBlendModeSaturation alpha:1.0];
    [path stroke];

}复制代码
  • 修改当前图形上下文的绘图区域可见,随后的绘图操作导致呈现内容只有发生在指定路径的填充区域

- (void)createAddClip{
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
    [[UIColor greenColor] setStroke];
    [path addClip];
    [path stroke];
}


作者:Mr_JIE
链接:https://juejin.cn/post/7022540680006205448

文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐