HTML5-canvas之绘制圆弧和贝塞尔曲线(3)

今天我们主要是学习如何绘制圆弧和贝塞尔曲线。

圆弧的绘制

圆弧可以理解为一个圆上的某部分线段,在canvas中,绘制一条圆弧的语法如下:

其中的 “开始角度” 和 “结束角度” 是相对360度的 顺时针 的极坐标而言的,可配合下图理解:

我们来一个例子,绘制一个圆心坐标为(80,80),半径为40,开始角度为30度,结束角度为90度,那么可以这样绘制:

其中开始角和结束角我们分别设定为“1/6Math.PI”和“1/2Math.PI”,是因为canvas里的角度是以PI(π)为单位的,在js中写作Math.PI,你可以把一个PI理解为180度,那么30度便是1/6个PI。上述代码效果如下:


开始角和结束角也可以是负值,则角度从0度开始以逆时针方式获取:

我们可以很轻松地来绘制一个完整的圆,将起始角设为0度,结束角设为360度(2*Math.PI)即可:

注意给圆填充颜色我们使用的是 .fill() 方法,和多边形的填充方式一样。


接着说说 arc() 的好兄弟 arcTo() 方法,它可以在两条线段之间连接起一条弧线,其语法如下

ctx.arcTo( 起点切线末端x坐标, 起点切线末端y坐标, 终点x坐标, 终点y坐标, 圆的半径r );

可以配合下图理解:

我们先不管什么“连接两条线段”的事情,单纯看下arcTo()绘制了怎样的一条圆弧:


那么我们利用arcTo()方法来连接两条直线吧:

需要知道的是 arc() 不会影响画笔的位置,而 arcTo() 会把画笔移到圆弧线的终点位置。


曲线的绘制

无论是arc()抑或arcTo(),均是绘制了一个正圆上的部分圆弧线段,下面讲讲更灵活的曲线的绘制。

首先介绍的是canvas中贝塞尔曲线的绘制。使用过AI等专业矢量制图软件的朋友相信能很好地理解这一部分。我们先看下在制图软件中用钢笔工具绘制一条贝塞尔曲线的过程:

可以看到每两点可以连成一条贝塞尔路径,且每一个点都有一条方位控制线来控制曲线的弯曲程度和走向,在canvas中也是以类似形式控制贝塞尔曲线的形状。

我们先来看看bezierCurveTo()的实现方式,它称作“三次方贝塞尔曲线”,其语法为:

其中CSx、CSy表示贝塞尔曲线起点方向控制线末端的x坐标和y坐标。CEx、CEy表示贝塞尔曲线终点方向控制线末端的x坐标和y坐标。Ex、Ey表示贝塞尔曲线终点坐标。

参考图如下,图中的贝塞尔曲线起点坐标为(20,20),终点坐标为(200,20),起点的方向控制线末端坐标为(20,100),终点的方向控制线末端坐标为(200,100):

有的朋友可能会问为何bezierCurveTo()方法没有起始点的参数,答案是起始点默认为bezierCurveTo()方法执行之前画笔所在的位置,我们可以通过ctx.moveTo(x,y)来确定起始点的位置。

如上图所示的贝塞尔曲线我们可以这样绘制:


我们可以绘制两条或者多条连在一起的贝塞尔曲线,从而塑造我们想要的曲线:


使用过矢量制图软件的朋友可能有个地方会困惑,那就是我们很多时候开始绘制一条曲线时(起点不做拉伸),该曲线的起点是没有任何方向控制线的,如下图:

如果我们要绘制一条起点不做方向控制的曲线,那么bezierCurveTo()方法就不再适用了。

针对这种情况,可以通过 quadraticCurveTo() 方法来解决,它称作“二次方贝塞尔曲线”,语法为

ctx.quadraticCurveTo( CEx, CEy, Ex, Ey );

其中CEx、CEy表示曲线终点方向控制线末端的x坐标和y坐标。Ex、Ey表示曲线终点坐标。至于曲线起点则跟bezierCurveTo()一样,为该方法执行前画笔所在的位置。


我们试着来绘制一条这样的曲线,它是我在AI中用钢笔工具绘制出来的:

它的矢量轮廓是这样的:

由于起点是没有方向控制线的,我们很容易知道得先绘制一条quadraticCurve,然后再紧接着绘制一条bezierCurve来完成这条曲线。

我们先确定下各点的坐标:

然后轻松写出代码:

效果杠杠的

建议有兴趣的朋友多实践,其中贝塞尔曲线部分的知识点可以通过AI等矢量设计软件来加深理解。共勉~ 啦啦啦 还有,大家元旦快乐啊!

有关链接

http://www.cnblogs.com/vajoy/p/3925190.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PPV课数据科学社区

数据挖掘知识脉络与资源整理(七)–饼图

? ? 简介 饼图英文学名为Sector Graph, 有名Pie Graph。常用于统计学模块。2D饼图为圆形,手画时,常用圆规作图。 仅排列在工作表的一...

30670
来自专栏calmound

CSS继承特殊

继承 CSS的某些样式具有继承性。 继承是一种规则,它允许样式不仅作用于某个特定html标签元素,而且应用于其后代    如:在p中的所有字体都为红色     ...

28850
来自专栏前端那些事

过渡与动画 - 缓动效果&基于贝塞尔曲线的调速函数

难题 给过渡和动画加上缓动效果是一种常见的手法(比如具有回弹效果的过渡过程)是一种流行的表现手法,可以让界面显得更加生动和真实:在现实世界中,物体A点到B点往往...

417110
来自专栏数据小魔方

sparklines迷你图系列6——Comparison(Columns)

今天分享sparklines迷你图中的Comparision图表类型中的Columns图表。 该图表说到底其实就是我们日常工作中最常用到的柱形图。 该图表的函数...

27940
来自专栏数据小魔方

散点图分割不同象限的技巧

今天跟大家聊一聊散点图中分割不同象限的辅助线制作技巧! ▽ 分割象限 在做完散点图之后 通常我们都很想知道这些点的分布是否存在某种趋势 如果趋势比较明显 用肉眼...

42570
来自专栏JackeyGao的博客

使用Python将两张照片透明重叠

透明重叠最主要用的是Image.blend方法(详情请看第二个代码块), 第一个代码块主要是将多个图片剪切到一张大图, 然后用这张大图和另外一张非剪切的大图进行...

38910
来自专栏机器之心

灵魂追问 | 教程那么多,你……看完了吗?

30990
来自专栏Petrichor的专栏

opencv: 阈值处理(cv2.threshold) 探究(图示+源码)

左半边为(单通道)源图片; 右半边为(阈值设为150,填充色设为100)在 不同阈值类型 的取值下生成的(单通道)阈值处理图片。

31840
来自专栏图形学与OpenGL

6.5编程实例-立方体透视投影

GLint winWidth = 600, winHeight = 600; //设置初始化窗口大小

22910
来自专栏生信技能树

用python编写验证码

作为一个用python的生信工程师,平时工作中除了用python来处理些文本文件和搭建流程,没事也想探索些其他有趣的功能。这几天就在网上学习了下如何用pytho...

43650

扫码关注云+社区

领取腾讯云代金券