当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS贝塞尔曲线画哆啦A梦的代码实例

iOS贝塞尔曲线画哆啦A梦的代码实例

2019年07月24日  | 移动技术网IT编程  | 我要评论

长得轻浮也违章,草原上升起不落的太阳歌词,艾伦希亚战记中文版

看到这张图,是不是觉得挺萌的,那是如何实现的呢?在ios中有一个类叫uibezierpath(贝塞尔曲线),这两天研究了一下uibezierpath和cashapelayer,根据别人分享的教程,画了这个萌萌的哆啦a梦。

uibezierpath: uibezierpath是在 uikit 中的一个类,继承于nsobject,可以创建基于矢量的路径.此类是core graphics框架关于path的一个oc封装。使用此类可以定义常见的圆形、多边形等形状 。我们使用直线、弧(arc)来创建复杂的曲线形状。每一个直线段或者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集合成为subpath。一个uibezierpath对象定义一个完整的路径包括一个或者多个subpaths。

cashapelayer: 继承于calayer。 每个cashapelayer对象都代表着将要被渲染到屏幕上的一个任意的形状(shape)。具体的形状由其path(类型为cgpathref)属性指定。 普通的calayer是矩形,所以需要frame属性。cashapelayer它本身没有形状,它的形状来源于其属性path 。cashapelayer有不同于calayer的属性,它从calayer继承而来的属性在绘制时是不起作用的。

基本用法:

画圆弧: + (instancetype)bezierpathwitharccenter:(cgpoint)center radius:(cgfloat)radius startangle:(cgfloat)startangle endangle:(cgfloat)endangle clockwise:(bool)clockwise;

  1. center表示圆心
  2. radius表示半径
  3. startangle表示开始角度
  4. endangle表示结束角度
  5. clockwise表示是否是顺时针方向

画二元曲线和三元曲线,一般和movetopoint配合使用。

  1. 二元曲线:- (void)addquadcurvetopoint:(cgpoint)endpoint controlpoint:(cgpoint)controlpoint
  2. 三元曲线:- (void)addcurvetopoint:(cgpoint)endpoint controlpoint1:(cgpoint)controlpoint1 controlpoint2:(cgpoint)controlpoint2

其中 endpoint表示:曲线的终点 ;controlpoint表示:画曲线的基准点

知道基本画法后我们就可以画哆啦a梦了。

1、先画头部。先画一个圆。

//  确定头部所在的圆心
  cgfloat headcornerradius=80;
  cgfloat arccenterx=self.view.frame.size.width/2;
  cgfloat arccentery= 120+headcornerradius;


  //画头部
  cashapelayer *headlayer=[[cashapelayer alloc] init];
  uibezierpath *headpath=[uibezierpath bezierpathwithroundedrect:cgrectmake(self.view.frame.size.width/2-headcornerradius, 120, headcornerradius*2, headcornerradius*2) cornerradius:headcornerradius];
  [self setlayer:headlayer path:headpath];

2、画脸部。画一个比头部小点的圆,与头部圆的底部内切。

 //脸
  cashapelayer *facelayer=[cashapelayer layer];
  uibezierpath *facepath=[uibezierpath bezierpathwitharccenter:cgpointmake(self.view.frame.size.width/2, 120+headcornerradius+10) radius:70 startangle:m_pi endangle:3*m_pi clockwise:yes];
  [self setlayer:facelayer path:facepath];

3、画眼部

  //左眼
  cashapelayer *lefteyelayer = [cashapelayer layer];
  uibezierpath *lefteyepath = [uibezierpath bezierpath];
  [lefteyepath movetopoint:cgpointmake(arccenterx-30, arccentery-25)];
  [lefteyepath addquadcurvetopoint:cgpointmake(arccenterx-15, arccentery-45) controlpoint:cgpointmake(arccenterx-30, arccentery-45)];
  [lefteyepath addquadcurvetopoint:cgpointmake(arccenterx, arccentery-25) controlpoint:cgpointmake(arccenterx, arccentery-45)];
  [lefteyepath addquadcurvetopoint:cgpointmake(arccenterx-15, arccentery-5) controlpoint:cgpointmake(arccenterx, arccentery-5)];
  [lefteyepath addquadcurvetopoint:cgpointmake(arccenterx-30, arccentery-25) controlpoint:cgpointmake(arccenterx-30, arccentery-5)];
  [self setlayer:lefteyelayer path:lefteyepath];

  //左眼珠
  cashapelayer *lefteyeballlayer = [cashapelayer layer];
  uibezierpath *lefteyeballpath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx-5, arccentery-30) radius:2.5 startangle:0 endangle:2*m_pi clockwise:yes];
  [self setlayer:lefteyeballlayer path:lefteyeballpath ];

  //右眼
  cashapelayer *righteyelayer = [cashapelayer layer];
  uibezierpath *righteyepath = [uibezierpath bezierpath];
  [righteyepath movetopoint:cgpointmake(arccenterx, arccentery-25)];
  [righteyepath addquadcurvetopoint:cgpointmake(arccenterx+15, arccentery-45) controlpoint:cgpointmake(arccenterx, arccentery-45)];
  [righteyepath addquadcurvetopoint:cgpointmake(arccenterx+30, arccentery-25) controlpoint:cgpointmake(arccenterx+30, arccentery-45)];
  [righteyepath addquadcurvetopoint:cgpointmake(arccenterx+15, arccentery-5) controlpoint:cgpointmake(arccenterx+30, arccentery-5)];
  [righteyepath addquadcurvetopoint:cgpointmake(arccenterx, arccentery-25) controlpoint:cgpointmake(arccenterx, arccentery-5)];
  [self setlayer:righteyelayer path:righteyepath ];

  //右眼珠
  cashapelayer *righteyeballlayer = [cashapelayer layer];
  uibezierpath *righteyeballpath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx+5, arccentery-30) radius:2.5 startangle:0 endangle:2*m_pi clockwise:yes];
  [self setlayer:righteyeballlayer path:righteyeballpath];

4、画鼻子、嘴巴、胡须

  //鼻子
  cashapelayer *noselayer = [cashapelayer layer];
  uibezierpath *nosepath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx, arccentery) radius:10 startangle:0 endangle:2*m_pi clockwise:yes];
  [self setlayer:noselayer path:nosepath ];

  //鼻子光晕
  cashapelayer *nosehalolayer = [cashapelayer layer];
  uibezierpath *nosehalopath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx-4, arccentery-5) radius:2.5 startangle:0 endangle:2*m_pi clockwise:yes];
  [self setlayer:nosehalolayer path:nosehalopath ];

  //嘴巴
  cashapelayer *mouthlayer = [cashapelayer layer];
  uibezierpath *mouthpath = [uibezierpath bezierpath];
  [mouthpath movetopoint:cgpointmake(arccenterx-60, arccentery+25)];
  [mouthpath addquadcurvetopoint:cgpointmake(arccenterx+60, arccentery+25) controlpoint:cgpointmake(arccenterx, arccentery+90)];
  [self setlayer:mouthlayer path:mouthpath];

  cashapelayer *mouthlayer1 = [cashapelayer layer];
  uibezierpath *mouthpath1 = [uibezierpath bezierpath];
  [mouthpath1 movetopoint:cgpointmake(arccenterx, arccentery+10)];
  [mouthpath1 addlinetopoint:cgpointmake(arccenterx, arccentery+55)];
  [self setlayer:mouthlayer1 path:mouthpath1];

  //胡须
  [self addbeardfrompoint:cgpointmake(arccenterx-58, arccentery-5) topoint:cgpointmake(arccenterx-15, arccentery+10) ];
  [self addbeardfrompoint:cgpointmake(arccenterx-68, arccentery+15) topoint:cgpointmake(arccenterx-15, arccentery+20) ];
  [self addbeardfrompoint:cgpointmake(arccenterx-61, arccentery+45) topoint:cgpointmake(arccenterx-15, arccentery+30) ];
  [self addbeardfrompoint:cgpointmake(arccenterx+58, arccentery-5) topoint:cgpointmake(arccenterx+15, arccentery+10) ];
  [self addbeardfrompoint:cgpointmake(arccenterx+68, arccentery+15) topoint:cgpointmake(arccenterx+15, arccentery+20) ];
  [self addbeardfrompoint:cgpointmake(arccenterx+61, arccentery+45) topoint:cgpointmake(arccenterx+15, arccentery+30) ];

5、画左手部分

 //左手
  cashapelayer *lefthandlayer = [cashapelayer layer];
  uibezierpath *lefthandpath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx-95, arccentery+110) radius:20 startangle:0 endangle:2*m_pi clockwise:yes];
  [self setlayer:lefthandlayer path:lefthandpath ];

  //左胳膊
  cgfloat distancextoarccenter = 80*cos(m_pi_2*4/9);
  cgfloat distanceytoarccenter = 80*sin(m_pi_2*4/9);
  cashapelayer *leftarmlayer = [cashapelayer layer];
  uibezierpath *leftarmpath = [uibezierpath bezierpath];
  [leftarmpath movetopoint:cgpointmake(arccenterx-distancextoarccenter, arccentery+distanceytoarccenter)];
  [leftarmpath addlinetopoint:cgpointmake(arccenterx-95, arccentery+90)];
  [leftarmpath addquadcurvetopoint:cgpointmake(arccenterx-75, arccentery+110) controlpoint:cgpointmake(arccenterx-92, arccentery+107)];
  [leftarmpath addlinetopoint:cgpointmake(arccenterx-distancextoarccenter+1.5, arccentery+95)];
  [self setlayer:leftarmlayer path:leftarmpath ];

6、画身体部分

//围巾
  cashapelayer *mufflerlayer = [cashapelayer layer];
  uibezierpath *mufflerpath = [uibezierpath bezierpath];
  [mufflerpath movetopoint:cgpointmake(arccenterx-distancextoarccenter, arccentery+distanceytoarccenter)];
  [mufflerpath addquadcurvetopoint:cgpointmake(arccenterx+distancextoarccenter, arccentery+distanceytoarccenter) controlpoint:cgpointmake(arccenterx, arccentery+109)];
  [mufflerpath addlinetopoint:cgpointmake(arccenterx+distancextoarccenter+2, arccentery+distanceytoarccenter+7)];
  [mufflerpath addquadcurvetopoint:cgpointmake(arccenterx-distancextoarccenter-4, arccentery+distanceytoarccenter+5) controlpoint:cgpointmake(arccenterx, arccentery+115)];
  [mufflerpath addlinetopoint:cgpointmake(arccenterx-distancextoarccenter, arccentery+distanceytoarccenter)];
  [self setlayer:mufflerlayer path:mufflerpath ];

  //身体
  cashapelayer *bodylayer = [cashapelayer layer];
  uibezierpath *bodypath = [uibezierpath bezierpath];
  [bodypath movetopoint:cgpointmake(arccenterx-distancextoarccenter, arccentery+distanceytoarccenter+7)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx-distancextoarccenter+5, arccentery+150) controlpoint:cgpointmake(arccenterx-distancextoarccenter+2, arccentery+140)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx-distancextoarccenter+3, arccentery+170) controlpoint:cgpointmake(arccenterx-distancextoarccenter, arccentery+160)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx-8, arccentery+170) controlpoint:cgpointmake(arccenterx-(distancextoarccenter+5)/2, arccentery+175)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx+8, arccentery+170) controlpoint:cgpointmake(arccenterx, arccentery+155)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx+distancextoarccenter-3, arccentery+170) controlpoint:cgpointmake(arccenterx+(distancextoarccenter+5)/2, arccentery+175)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx+distancextoarccenter-5, arccentery+150) controlpoint:cgpointmake(arccenterx+distancextoarccenter-2, arccentery+160)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx+distancextoarccenter, arccentery+distanceytoarccenter+8) controlpoint:cgpointmake(arccenterx+distancextoarccenter-2, arccentery+140)];
  [bodypath addquadcurvetopoint:cgpointmake(arccenterx-distancextoarccenter, arccentery+distanceytoarccenter+7) controlpoint:cgpointmake(arccenterx, arccentery+115)];
  [self setlayer:bodylayer path:bodypath ];


  //左脚
  cashapelayer *leftfootlayer = [cashapelayer layer];
  uibezierpath *leftfootpath = [uibezierpath bezierpath];
  [leftfootpath movetopoint:cgpointmake(arccenterx-distancextoarccenter+3, arccentery+170)];
  [leftfootpath addquadcurvetopoint:cgpointmake(arccenterx-distancextoarccenter+3, arccentery+195) controlpoint:cgpointmake(arccenterx-distancextoarccenter-20, arccentery+185)];
  [leftfootpath addquadcurvetopoint:cgpointmake(arccenterx-13, arccentery+195) controlpoint:cgpointmake(arccenterx-(distancextoarccenter+10)/2, arccentery+200)];
  [leftfootpath addquadcurvetopoint:cgpointmake(arccenterx-10, arccentery+170) controlpoint:cgpointmake(arccenterx+8, arccentery+187)];
  [self setlayer:leftfootlayer path:leftfootpath ];


  //右脚
  cashapelayer *rightfootlayer = [cashapelayer layer];
  uibezierpath *rightfootpath = [uibezierpath bezierpath];
  [rightfootpath movetopoint:cgpointmake(arccenterx+10, arccentery+170)];
  [rightfootpath addquadcurvetopoint:cgpointmake(arccenterx+15, arccentery+195) controlpoint:cgpointmake(arccenterx-12, arccentery+185)];
  [rightfootpath addquadcurvetopoint:cgpointmake(arccenterx+distancextoarccenter-5, arccentery+195) controlpoint:cgpointmake(arccenterx+(distancextoarccenter+20)/2, arccentery+200)];
  [rightfootpath addquadcurvetopoint:cgpointmake(arccenterx+distancextoarccenter-3, arccentery+170) controlpoint:cgpointmake(arccenterx+distancextoarccenter+18, arccentery+185)];
  [self setlayer:rightfootlayer path:rightfootpath];

  //肚子
  cashapelayer *bellylayer = [cashapelayer layer];
  uibezierpath *bellypath = [uibezierpath bezierpath];
  [bellypath movetopoint:cgpointmake(arccenterx-30, arccentery+80)];
  [bellypath addcurvetopoint:cgpointmake(arccenterx-30, arccentery+150) controlpoint1:cgpointmake(arccenterx-65, arccentery+95) controlpoint2:cgpointmake(arccenterx-60, arccentery+140)];
  [bellypath addquadcurvetopoint:cgpointmake(arccenterx+30, arccentery+150) controlpoint:cgpointmake(arccenterx, arccentery+160)];
  [bellypath addcurvetopoint:cgpointmake(arccenterx+30, arccentery+80) controlpoint1:cgpointmake(arccenterx+60, arccentery+140) controlpoint2:cgpointmake(arccenterx+65, arccentery+95)];
  [bellypath addquadcurvetopoint:cgpointmake(arccenterx-30, arccentery+80) controlpoint:cgpointmake(arccenterx, arccentery+92)];
  [self setlayer:bellylayer path:bellypath ];

  //铃铛
  cashapelayer *belllayer = [cashapelayer layer];
  uibezierpath *bellpath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx, arccentery+97) radius:15 startangle:0 endangle:2*m_pi clockwise:yes];
  [self setlayer:belllayer path:bellpath ];


  //铃铛上的线
  cashapelayer *belllinelayer = [cashapelayer layer];
  uibezierpath *belllinepath = [uibezierpath bezierpath];
  [belllinepath movetopoint:cgpointmake(arccenterx-(sqrt(pow(15.0, 2)-pow(5.0, 2))), arccentery+92)];
  [belllinepath addlinetopoint:cgpointmake(arccenterx+(sqrt(pow(15.0, 2)-pow(5.0, 2))), arccentery+92)];
  [belllinepath movetopoint:cgpointmake(arccenterx+(sqrt(pow(15.0, 2)-pow(2.0, 2))), arccentery+95)];
  [belllinepath addlinetopoint:cgpointmake(arccenterx-(sqrt(pow(15.0, 2)-pow(2.0, 2))), arccentery+95)];
  [self setlayer:belllinelayer path:belllinepath ];


  //铃铛上的小圆点
  cashapelayer *bellcirlayer = [cashapelayer layer];
  uibezierpath *bellcirpath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx, arccentery+102) radius:2.5 startangle:0 endangle:2*m_pi clockwise:yes];
  [bellcirpath movetopoint:cgpointmake(arccenterx, arccentery+104.5)];
  [bellcirpath addlinetopoint:cgpointmake(arccenterx, arccentery+112)];
  [self setlayer:bellcirlayer path:bellcirpath ];

  //口袋
  cashapelayer *baglayer = [cashapelayer layer];
  uibezierpath *bagpath = [uibezierpath bezierpath];
  [bagpath movetopoint:cgpointmake(arccenterx-40, arccentery+112)];
  [bagpath addquadcurvetopoint:cgpointmake(arccenterx+40, arccentery+112) controlpoint:cgpointmake(arccenterx, arccentery+120)];
  [bagpath addcurvetopoint:cgpointmake(arccenterx-40, arccentery+112) controlpoint1:cgpointmake(arccenterx+28, arccentery+160) controlpoint2:cgpointmake(arccenterx-28, arccentery+160)];
  [self setlayer:baglayer path:bagpath ];

7、画右手部分

  //右手
  cashapelayer *righthandlayer = [cashapelayer layer];
  uibezierpath *righthandpath = [uibezierpath bezierpathwitharccenter:cgpointmake(arccenterx+85*cos(27/180.0*m_pi), arccentery-85*sin(27/180.0*m_pi)) radius:20 startangle:0 endangle:2*m_pi clockwise:yes];
  [self setlayer:righthandlayer path:righthandpath ];


  //右胳膊
  cashapelayer *rightarmlayer = [cashapelayer layer];
  uibezierpath *rightarmpath = [uibezierpath bezierpath];
  [rightarmpath movetopoint:cgpointmake(arccenterx+80*cos(13/180.0*m_pi), arccentery-80*sin(13/180.0*m_pi))];
  [rightarmpath addquadcurvetopoint:cgpointmake(arccenterx+distancextoarccenter, arccentery+distanceytoarccenter) controlpoint:cgpointmake(arccenterx+80*cos(13/180.0*m_pi)+9, arccentery+20)];
  [rightarmpath addlinetopoint:cgpointmake(arccenterx+distancextoarccenter, arccentery+distanceytoarccenter+25)];
  [rightarmpath addquadcurvetopoint:cgpointmake(arccenterx+93*cos(15/180.0*m_pi), arccentery-93*sin(15/180.0*m_pi)) controlpoint:cgpointmake(arccenterx+90*cos(13/180.0*m_pi)+15, arccentery+25)];
  [rightarmpath addquadcurvetopoint:cgpointmake(arccenterx+80*cos(13/180.0*m_pi), arccentery-80*sin(13/180.0*m_pi)) controlpoint:cgpointmake(arccenterx+80*cos(13/180.0*m_pi)+5, arccentery-93*sin(15/180.0*m_pi)+5)];
  [self setlayer:rightarmlayer path:rightarmpath];

  uilabel *label = [[uilabel alloc] initwithframe:cgrectmake(self.view.frame.size.width/2+90, 120, 70, 30)];
  label.textalignment = nstextalignmentcenter;
  label.textcolor = [uicolor colorwithred:21/255.0 green:159/255.0 blue:237/255.0 alpha:1];
  label.text = @"hello";
  label.font = [uifont fontwithname:@"chalkduster" size:20];
  [self.view addsubview:label];

  cabasicanimation *animation = [cabasicanimation animationwithkeypath:@"transform.scale"];
  animation.fromvalue = @(0);
  animation.tovalue = @(1);
  animation.duration = 0.5f;
  [label.layer addanimation:animation forkey:nil];

8、给各个部位上颜色

 //上色
  facelayer.fillcolor = [uicolor whitecolor].cgcolor;
  lefteyelayer.fillcolor = [uicolor whitecolor].cgcolor;
  righteyelayer.fillcolor = [uicolor whitecolor].cgcolor;
  lefteyeballlayer.fillcolor = [uicolor blackcolor].cgcolor;
  righteyeballlayer.fillcolor = [uicolor blackcolor].cgcolor;
  noselayer.fillcolor = [uicolor redcolor].cgcolor;
  nosehalolayer.fillcolor = [uicolor whitecolor].cgcolor;
  headlayer.fillcolor = [uicolor colorwithred:21/255.0 green:159/255.0 blue:237/255.0 alpha:1].cgcolor;
  leftarmlayer.fillcolor = [uicolor colorwithred:21/255.0 green:159/255.0 blue:237/255.0 alpha:1].cgcolor;
  lefthandlayer.fillcolor = [uicolor whitecolor].cgcolor;
  mufflerlayer.fillcolor = [uicolor redcolor].cgcolor;
  bellylayer.fillcolor = [uicolor whitecolor].cgcolor;
  belllayer.fillcolor = [uicolor yellowcolor].cgcolor;
  bodylayer.fillcolor = [uicolor colorwithred:21/255.0 green:159/255.0 blue:237/255.0 alpha:1].cgcolor;
  righthandlayer .fillcolor=[uicolor whitecolor].cgcolor ;
  rightarmlayer .fillcolor=[uicolor colorwithred:21/255.0 green:159/255.0 blue:237/255.0 alpha:1] .cgcolor;

这样,一个简单的哆啦a梦就实现了。

文中只展示了重要部分的代码,如果有需要,可以看完整的demo,同时demo里面也展示了uibezierpath和cashapelayer基本的画图方法。

demo地址 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网