写在后面
iOS设置圆角的属性商讨已经是三个新瓶装旧酒的难题了,有目共睹,假设直接使用layer
的cornerRadius
+
masksToBounds
虽说能够很有益于的成功圆角设置,但会唤起离屏渲染,导致质量难题,在列表视图中过多的圆角设置就能够导致滑动卡顿,今后主流的方案正是在赢得图片的一刻敞开异步线程对图片举办相应的圆角管理,把图纸管理成想要的图纸在回到主线程举办展示,想要便捷的达标此指标推荐YY大神的YYWebImage
,其在获取图片的时候的时候提供了二个transform
的block
,在此block
中你能够完毕图片的拍卖工作,可是在实质上的应用中,小编感觉第三种方案或许有一点点不方便人民群众的地点,具体如下:
1、对于网络图片,大许多要提前设置展位图,假若美术职业未有提供圆角占位图片,你必要相应的对占位图片张开圆角管理;
2、对于混合视图供给圆角的,举例下图,图片上有二个Label,label也要求圆角化,你也得对label举办独立的管理(这里笔者有个小tip:倘若必需运用这种艺术,小编的做法是生成一张左下角和右下角圆角化的豆沙色背景图片,然后利用colorWithPatternImage
将图纸设置label的背景象,那样你没有须求为这些米色的圆角地图别的创立叁个视图)
图片上有Label.png
3、假使多处需求重复使用同叁个图片地址,使用YYWebImage
时,其会将tranform后的图样缓存起来,所以就能现出,假令你在三个地点圆角化了该图片,在另二个地点选择时依旧会是圆角化的图形,那显然在临时是不满足须求的,可是你能够应用分歧的YYWebImageManager
来治本均等图片地址而急需分歧transform的图片;
综述,固然能够透过有个别艺术减轻上述难点,假若有贰特性质优良且能制止上诉难题爆发的圆角化方案就更加好了。
cornerRadius属性影响layer呈现的background颜色和前景框border,对layer的contents不起功能。故二个imgView(类型为UIImageView)的image不为空,设置imgView.layer的cornerRadius,是看不出展现圆角效果的,因为image是imgView.layer的contents部分。
小编的方案
要幸免上述难点,我们就无法从修改图片动手了,依旧须求从视图档期的顺序入手,笔者动用的方案其实也一定轻便,要是有些视图要求圆角化,笔者只须要在该视图上增添二个子layer到最上层,用于覆盖该视图及其子视图,设置layer的图片为刚刚能够掩饰成所需圆角样子况兼图片颜色刚好是该视图父视图的背景颜色就达到达到规定的标准想要的效果的,由于该遮罩layer在最上层,所以对于地点所波及的第4个短处中的Label,也许有意还是无意着遮罩了,所以不要求重复拍卖,当然由于我们是在视图等级次序而非图片档案的次序管理的圆角,上边的首先个和第三个缺欠也一纸空文了,那样实在相当粗略的缓慢解决的上诉三个毛病,上面来探问相关的代码:
1、首先是绘制遮掩layer的图层图片,当然我们得以让美术职业切图给大家,可是借使对于每种尺寸的视图都去切图的话,职业量就相应增大了,其实大家值须要绘制一张如下的图形,借使是空荡荡,请点击图片查看
带边框.png
不带边框.png
先来探视绘制代码
/**我创建了一个分类用于创建相应的遮罩图片*/@implementation UIImage (XWAddForRoundedCorner)/**提供一个在一个指定的size中绘制图片的便捷方法*/+ (UIImage *)xw_imageWithSize:size drawBlock:(CGContextRef context))drawBlock { if (!drawBlock) return nil; UIGraphicsBeginImageContextWithOptions(size, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); if return nil; drawBlock; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image;}/**绘制方法的具体逻辑,遮罩图片的逻辑是绘制一个矩形,然后在绘制一个相应的圆角矩形,然后填充矩形和圆角矩形的中间部分为父视图的背景色*/+ (UIImage *)xw_maskRoundCornerRadiusImageWithColor:(UIColor *)color cornerRadii:cornerRadii size:size corners:(UIRectCorner)corners borderColor:(UIColor *)borderColor borderWidth:borderWidth{ return [UIImage xw_imageWithSize:size drawBlock:^(CGContextRef _Nonnull context) { CGContextSetLineWidth(context, 0); [color set]; CGRect rect = CGRectMake(0, 0, size.width, size.height); //绘制一个矩形,这里发-0.3是为了防止边缘的锯齿, UIBezierPath *rectPath = [UIBezierPath bezierPathWithRect:CGRectInset(rect, -0.3, -0.3)]; //绘制圆角矩形,这里的0.3是为了防止内边框的锯齿 UIBezierPath *roundPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, 0.3, 0.3) byRoundingCorners:corners cornerRadii:cornerRadii]; [rectPath appendPath:roundPath]; CGContextAddPath(context, rectPath.CGPath); //注意要用EOFill方式进行填充而非Fill方式 CGContextEOFillPath; //如下是绘制边框,原理依旧是绘制一个外边框然后根据边框宽度绘制一个内边框同样采取EOFill的方式进行填充即可 if (!borderColor || !borderWidth) return; [borderColor set]; UIBezierPath *borderOutterPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:cornerRadii]; UIBezierPath *borderInnerPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadii:cornerRadii]; [borderOutterPath appendPath:borderInnerPath]; CGContextAddPath(context, borderOutterPath.CGPath); CGContextEOFillPath; }];}@end
上述的绘图方法充足利用了系统绘制圆角的法子bezierPathWithRoundedRect
+
EOFill
,其实最初始作者是怀想自身绘制百分之三十的圆弧来创设圆角的,后来察觉不但代码多了过多,何况绘制出来的圆角始终不曾系统这些绘制方法的一唱三叹,笔者打字与印刷的系统的圆角路线,开掘其应有不是叁分四分之二圆,开掘她的调控点取值有个别意外,作者也不太精通是何等取的,不过意义实在要好一点,综上说述采纳如上的EOFill
主意取巧,绘制的圆角图片可以达到规定的标准和类别的cornerRadius
大同小异的效果!
2、对于绘制的图样,大家相应展咸宁存,当蒙受颜色,圆角以及边框等属性完全同样的绘图诉求时候,大家得以立即复用,幸免频仍创设
挪动使用优化到结尾根本照旧看FPS品质、内部存款和储蓄器占用等地点。离屏渲染也是故态复萌的八个主题素材,本文侧重视在大面积导致离屏渲染的要素及缓和方案。
iOS设置圆角的八种方法,和广大的离屏渲染Say。小小的圆角难点,不荒谬状态下,我们不必要过多关怀,但当荧屏内比非常多的时候,依旧有不能缺少通晓下品质难题的
这种场合下将layer的masksToBounds属性设置为YES,能够准确的绘图出圆角效应。可是cornerRadius>0,masksToBounds=YES,会触发GPU的离屏渲染,当一个显示屏上有多处触发离屏渲染,会影响属性。通过勾选Instruments->Core
Animation->Color Offscreen-Rendered
Yellow,能够看看荧屏上触发离屏渲染的会被渲染成铁青。离屏渲染的代价高昂,苹果也发觉到会发生质量难题,所以iOS9后头的系统里能不发生离屏渲染的地方也就不用离屏渲染了。比方对UIImageView里png图片设置圆角不会触发离屏渲染。
优缺点
优点的话,首倘若幸免了去消除地点说道提到的多少个难点,假设你有遭遇下面3个难题的麻烦,作者觉着那是特出不错的方案
再罗列缺点:
1、由于创设图片必要三个背景观,该背景象源于须求隐蔽视图的父视图的水彩,若是该父视图的水彩不是纯色或然存在透明的话,此时该方法就不适用了,此时照旧应当利用拍卖图片的法子来缓和;
2、若是父视图的颜色会变化,比如点击cell的时候,此刻您必要同不时候创新遮罩图片为相应颜色的图形,所以供给多写一些代码。
那正是说为啥离屏渲染会唤起品质难点?
OpenGL中,GPU荧屏渲染有三种情势: On-Screen Rendering 和 Off-Screen
Rendering
,当前荧屏渲染没有须要十一分创设新的缓存,也不需求敞开新的上下文,绝对于离屏渲染品质越来越好。可是受当前显示器渲染的局限因素限制(唯有自个儿上下文、显示屏缓存有限等),当前显示屏渲染有个别景况下的渲染消除不了的,就利用到离屏渲染。离屏渲染的总体经过需求切换上下文情形,先从
当前显示屏切换成离屏,等收尾后,又要将上下文意况切换回来.那也是为啥会开销质量的来由了。
离屏渲染引发因素有 cornerRadius、shadows、masks、edge
antialiasing、group opacity、shouldRasterize
等,至于检查评定离屏渲染的工具 Instruments的Core Animation
就非常的少说了。本文重要介绍 安装圆角 和 阴影 的方案。
一、设置CALayer的cornerRadius
cornerRadius属性影响layer呈现的background颜色和前景框border,对layer的contents不起成效。
因此二个imgView(类型为UIImageView)的image不为空,设置imgView.layer的cornerRadius,是看不出彰显圆角功用的,因为image是imgView.layer的contents部分。
这种状态下将layer的masksToBounds属性设置为YES,能够准确的绘图出圆角效果。
可是cornerRadius>0,masksToBounds=YES,会触发GPU的离屏渲染,当多个显示屏上有多处触发离屏渲染,会影响属性。
(假设查阅品质轮廓,可参照翻开那篇:通过勾选Instruments->Core
Animation->Color Offscreen-Rendered
Yellow,能够看出显示屏上触发离屏渲染的会被渲染全日青。)
离屏渲染会骤降fps,苹果也意识到会产生质量难点,所以iOS9未来的系统里能不产生离屏渲染的地点也就毫无离屏渲染了。比方对UIImageView里png图片设置圆角不会触发离屏渲染。
1、对contents为空的视图设置圆角
view.backgroundColor = [UIColor redColor];
view.layer.cornerRadius = 25;
//UILabel设置backgroundColor的行为被更改,不再是设定layer的背景色而是为contents设置背景色
label.layer.backgroundColor = aColor
label.layer.cornerRadius = 5
2、对contents不为空的视图设置圆角
imageView.image = [UIImage imageNamed:@"img"];
imageView.image.layer.cornerRadius = 5;
imageView.image.layer.masksToBounds = YES;
此地拉开一下,借使对一个label或button设置圆角,也足以使用layer.backgroundColor和layer.cornerRadius设置,而没有须求layer.maskstoBounds。
那般不会触发离屏渲染,所以ios9之后,可以直接那样做。
1.对contents为空的视图设置圆角
封装
对此此方案,笔者封装了二个简便的UIView
的分类UIView+XWAddForRoundedCorner
来实现指标,github地址是XWCornerRadius
,此分类分成轻巧唯有3个API
,且代码只有200行,未有任何依赖,具体API如下:
/** 设置一个四角圆角 @param radius 圆角半径 @param color 圆角背景色 */- xw_roundedCornerWithRadius:radius cornerColor:(UIColor *)color;/** 设置一个普通圆角 @param radius 圆角半径 @param color 圆角背景色 @param corners 圆角位置 */- xw_roundedCornerWithRadius:radius cornerColor:(UIColor *)color corners:(UIRectCorner)corners;/** 设置一个带边框的圆角 @param cornerRadii 圆角半径cornerRadii @param color 圆角背景色 @param corners 圆角位置 @param borderColor 边框颜色 @param borderWidth 边框线宽 */- xw_roundedCornerWithCornerRadii:cornerRadii cornerColor:(UIColor *)color corners:(UIRectCorner)corners borderColor:(UIColor *)borderColor borderWidth:borderWidth;
您只必要调用相应的API就会一鼓作气叁个圆角 +
边框的遮罩效果,同样遮罩图片的复用作者也做了连带管理了,具体使用如下:
[headerView xw_roundedCornerWithCornerRadii:XWSizeMake cornerColor:[UIColor whiteColor] corners:UIRectCornerAllCorners borderColor:[UIColor redColor] borderWidth:widthRatio];
工程的demo中带有二个之类的列表(该截图来自很老的ipod),演示了现实的选取情势,请自行查看:
demo列表.gif
设置圆角
常规做法:
//只需要设置layer层的两个属性 //设置圆角 imageView.layer.cornerRadius = imageView.frame.size.width / 2; //将多余的部分切掉 imageView.layer.masksToBounds = YES;
此地提供二种制止离屏渲染的方案
- 1.视图上增添一个子layer到最上层,用于覆盖该视图及其子视图,设置layer的图形为刚刚能够遮蔽成所需圆角样子,而且图片颜色刚好是该视图父视图的背景颜色就高达想要的作用。原版的书文地址
,该作者写的很好,封装了二个UIView的分类,3个API,分别是
安装二个四角圆角,设置三个点名地点的圆角,设置二个带边框的圆角
。github地址
/** 设置一个四角圆角 @param radius 圆角半径 @param color 圆角背景色 */- xw_roundedCornerWithRadius:radius cornerColor:(UIColor *)color;/** 设置一个普通圆角 @param radius 圆角半径 @param color 圆角背景色 @param corners 圆角位置 */- xw_roundedCornerWithRadius:radius cornerColor:(UIColor *)color corners:(UIRectCorner)corners;/** 设置一个带边框的圆角 @param cornerRadii 圆角半径cornerRadii @param color 圆角背景色 @param corners 圆角位置 @param borderColor 边框颜色 @param borderWidth 边框线宽 */- xw_roundedCornerWithCornerRadii:cornerRadii cornerColor:(UIColor *)color corners:(UIRectCorner)corners borderColor:(UIColor *)borderColor borderWidth:borderWidth;
下载下来这些分类直接拖入工程就足以行使了,调用很便利,然则使用的时候会意识,那八个API都亟待传一个参数
cornerColor ,所以也致使了这一个意义的受制,即
澳门葡京备用网址 ,借使该父视图的颜料不是纯色,此时该措施就不适用了,同样
万一父视图的颜色会变化,这完成起来的代码也不那么优雅,如下图,有一点点难堪,这里引出了第三种方案。
边角颜色与背景观不符
- 2.因此修改layer.mask,首先通过贝塞尔曲线创建基于矢量的门道,传递给CAShapeLayer实行渲染。路线闭环,再把绘制出的Shape赋值给layer.mask,在Mask范围之外的Layer将不被展现进而到达圆角效应。代码完毕很轻便,如下:
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(130, 330, 100, 100)]; [btn setBackgroundColor:[UIColor colorWithRed:(226.0 / 255.0) green:(113.0 / 255.0) blue:(19.0 / 255.0) alpha:1]]; [backgroundImageView addSubview:btn]; //绘制曲线路径 UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:btn.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:btn.bounds.size]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; //设置大小 maskLayer.frame = btn.bounds; //设置图形样子 maskLayer.path = maskPath.CGPath; btn.layer.mask = maskLayer;
效果图:
个体感到第三种方案更简约而且意义扩展性越来越强些
二、设置CALayer的mask
由此设置view.layer的mask属性,能够将另叁个layer盖在view上,也能够设置圆角,可是mask一样会触发离屏渲染。
有两种方法来生成遮罩:
一是因而图形生成,图片的反射率影响着view绘制的折射率,图片遮罩折射率为1的有个别view被绘制作而成的光滑度为0,相反图片遮罩折射率为0的有的view被绘制作而成的反射率为1。
二是透过贝塞尔曲线生成,view中曲线描述的样子部分会被绘制出来。
// 通过图片生成遮罩,
UIImage *maskImage = [UIImage imageNamed:@"someimg"];
CALayer *mask = [CALayer new];
mask.frame = CGRectMake(0, 0, maskImage.size.width, maskImage.size.height);
mask.contents = (__bridge id _Nullable)(maskImage.CGImage);
view.layer.mask = mask;
//通过贝塞尔曲线生成
CAShapeLayer *mask = [CAShapeLayer new];
mask.path = [UIBezierPath bezierPathWithOvalInRect:view.bounds].CGPath;
view.layer.mask = mask;
view.backgroundColor = [UIColor redColor];view.layer.cornerRadius =
25;
写在最终
对于此措施自己一度做了简要的测量试验,品质照旧杰出不错的,就算有图层混合,可是相对于离屏渲染,都以没不时,如上海体育场地在自家的老ipod的上也特别流畅,大家能够自行尝试,越多的有关这三种方案的质量相比较,网络也已经重重了,大家能够自行检索,当然你也足以动用YYWebImage
来拍卖图片的尺寸来更为优化图片的显得,
倘使在好几非常复杂的气象想要进一步提升流畅度,YYKit的源码以及
YY大神关于质量的相干文章相对值得一再阅读,但是对于优化的千姿百态,作者以为依旧先思量须要的兑现,再来思虑质量优化最佳,所谓过早的品质优化都以魔鬼嘛~~~对于该圆角思路假诺有疑问招待建议,若是感觉有扶助,多谢star,再复习叁次github地址:XWCornerRadius
安装阴影
平日做法:
//阴影的颜色self.imageView.layer.shadowColor= [UIColorblackColor].CGColor;//阴影的透明度self.imageView.layer.shadowOpacity=0.8f;//阴影的圆角self.imageView.layer.shadowRadius=4;//阴影偏移量self.imageView.layer.shadowOffset=CGSizeMake;
优化方案:幸免对shadowOffset直接改动,通过调用setShadowPath来提供贰个CGPath给视图的Layer,向Core
Animation提供渲染的View的形象Shape,就能够削减离屏渲染总结
[self.imageView.layer setShadowPath:[[UIBezierPath bezierPathWithRect:myView.bounds] CGPath]];
填补:当使用阴影的视图形状发生变化时,即shadowPath并不会尾随CALayer的bounds属性进行转移,所以在layer的bounds发生变化以往必要手动更新shadowPath技艺让其适配新的bounds。具体推荐看那篇小说
至于分界面流畅如若想要深层索求可以看 YYKit作者 写的稿子iOS
保持分界面流畅的技术。该文章从荧屏彰显图像的法规,到革新的方案都有详实介绍。
谢谢各位,应接指教!
三、通过Core Graphics重新绘制带圆角的视图
因此CPU重新绘制一份带圆角的视图来实现圆角效果,会大大扩充CPU的承负,并且一定于多了一份视图拷贝会扩充内部存款和储蓄器费用。然则就显得品质而言,由于尚未触发离屏渲染,所以能保险较高帧率。下例是绘制多个圆形图片,绘制另外UIView并无本质不一致。重新绘制的进度能够交由后台线程来拍卖。
@implementation UIImage (CircleImage)
- (UIImage *)drawCircleImage {
CGFloat side = MIN(self.size.width, self.size.height);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(side, side), false, [UIScreen mainScreen].scale);
CGContextAddPath(UIGraphicsGetCurrentContext(),
[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, side, side)].CGPath);
CGContextClip(UIGraphicsGetCurrentContext());
CGFloat marginX = -(self.size.width - side) / 2.f;
CGFloat marginY = -(self.size.height - side) / 2.f;
[self drawInRect:CGRectMake(marginX, marginY, self.size.width, self.size.height)];
CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return output;
}
@end
//在需要圆角时调用如下
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *img = [[UIImage imageNamed:@"image.png"] drawCircleImage];
dispatch_async(dispatch_get_main_queue(), ^{
view.image = img;
});
});
其实感觉这种方式有内存弊端,我测试过几次,当屏幕内大概200左右时,偶发一次会崩溃。
//UILabel设置backgroundColor的表现被退换,不再是设定layer的背景观而是为contents设置背景象
四、通过混合图层
此办法就是在要增多圆角的视图上再叠合二个片段透明的视图,只对圆角部分实行屏蔽。其实就是中等圆形部分透明,不遮挡尾部的控件,不过与此同期也亟需遮挡颜色和view背景象一致才行。
此办法纵然是最优解,未有离屏渲染,未有额外的CPU计算,然则利用范围有限。
label.layer.backgroundColor = aColor
总结
- 在可以动用混合图层遮挡的气象下,优先选取第五种格局。
- 哪怕是非iOS9以上系统,第一种格局在综合质量上如故强于后两个,iOS9上述由于并未有了离屏渲染更是首要推荐。
- 方法二和措施三出于采用了贝塞尔曲线,都得以答应复杂的圆角。只然则前面三个牺牲帧率,前者须要大批量计算和增加部分内部存储器,要求实情分别选用。
enjoy~
label.layer.cornerRadius = 5
2.对contents不为空的视图设置圆角
imageView.image = [UIImage imageNamed:@”img”];
imageView.image.layer.cornerRadius = 5;
imageView.image.layer.masksToBounds = YES;
因而设置view.layer的mask属性,能够将另三个layer盖在view上,也可以设置圆角,可是mask同样会触发离屏渲染。
有三种形式来生成遮罩,一是因而图形生成,图片的发光度影响着view绘制的光滑度,图片遮罩光滑度为1的一部分view被绘制作而成的光滑度为0,相反图片遮罩光滑度为0的一对view被绘制作而成的光滑度为1。二是由此贝塞尔曲线生成,view中曲线描述的造型部分会被绘制出来。
// 通过图形生成遮罩,
UIImage *maskImage = [UIImage imageNamed:@”someimg”];
CALayer *mask = [CALayer new];
mask.frame = CGRectMake(0, 0, maskImage.size.width,
maskImage.size.height);
mask.contents = (__bridge id _Nullable)(maskImage.CGImage);
view.layer.mask = mask;
//通过贝塞尔曲线生成
CAShapeLayer *mask = [CAShapeLayer new];
mask.path = [UIBezierPath
bezierPathWithOvalInRect:view.bounds].CGPath;
view.layer.mask = mask;
由此CPU重新绘制一份带圆角的视图来兑现圆角效果,会大大扩展CPU的负责,何况一定于多了一份视图拷贝会扩充内部存款和储蓄器开支。可是就显得质量来讲,由于并未触发离屏渲染,所以能保持较高帧率。下例是绘制壹个圆形图片,绘制另外UIView并无本质区别。重新绘制的进程能够交由后台线程来拍卖。
@implementation UIImage (CircleImage)
– (UIImage *)drawCircleImage {
CGFloat side = MIN(self.size.width, self.size.height);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(side, side), false,
[UIScreen mainScreen].scale);
CGContextAddPath(UIGraphicsGetCurrentContext(),
[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, side,
side)].CGPath);
CGContextClip(UIGraphicsGetCurrentContext;
CGFloat marginX = -(self.size.width – side) / 2.f;
CGFloat marginY = -(self.size.height – side) / 2.f;
[self drawInRect:CGRectMake(marginX, marginY, self.size.width,
self.size.height)];
CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return output;
}
@end
//在须要圆角时调用如下
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0), ^{
UIImage *img = [[UIImage imageNamed:@”image.png”] drawCircleImage];
dispatch_async(dispatch_get_main_queue(), ^{
view.image = img;
});
});
此格局便是在要加多圆角的视图上再叠合二个有的透明的视图,只对圆角部分开展掩盖。图层混合的发光度管理格局与mask正好相反。此措施固然是最优解,没有离屏渲染,未有额外的CPU总括,不过利用范围有限。
在能够运用混合图层遮挡的景观下,优用第多种办法。
就算是非iOS9之上系统,第一种办法在综合品质上依旧强于后两个,iOS9以上由于未有了离屏渲染更是首荐。
方法二和办法三是因为使用了贝塞尔曲线,都足以回答犬牙交错的圆角。只然则前面一个捐躯帧率,前面一个需求多量乘除和扩大部分内部存款和储蓄器,须要实际情状分别选择。