JavaScript 之 canvas(五)-- 椭圆、橡皮

原文地址: https://www.jeremyjone.com/490/, 转载请注明。


椭圆

通过前面的文章,我们已经可以绘制大部分图形以及文字。但是,在canvas中,椭圆是一个复杂的存在,本身我们上学时学习椭圆本身也是一个复杂的结构。我看了很多画椭圆的方案,大部分分为两类:

  • 第一类是 使用arc()画一个圆形,然后将其缩放变形,完成一个椭圆。
  • 第二类是 使用贝塞尔曲线,即使用多条贝塞尔曲线混合拼接为一个椭圆。

经过我的实际测试,采用我认为比较简单并且显示效果比较好的方式,使用贝塞尔曲线的方式绘制椭圆。

刚才说过,贝塞尔的方式是使用多条曲线拼接,一个椭圆可以是两条曲线、三条曲线,或四条甚至更多曲线拼接。我这里使用两条就够了,而且很大程度减少我们的计算量。

关于贝塞尔曲线

贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。

canvas中,使用bezierCurveTo()方法来绘制贝塞尔曲线,该方法通过使用表示三次贝塞尔曲线的指定控制点,向当前路径添加一个点。

  • 提示:三次贝塞尔曲线需要三个点。前两个点是用于三次贝塞尔计算中的控制点,第三个点是曲线的结束点。曲线的开始点是当前路径中最后一个点。如果路径不存在,那么请使用 beginPath() 和 moveTo() 方法来定义开始点。

file

** 以上摘自HTML5 canvas bezierCurveTo()方法说明

通过贝塞尔曲线绘制椭圆

通过上图,我们可以清楚看到绘制一条贝塞尔曲线的基本要素。

所以,我们的椭圆应该大致如下(纯鼠标绘制,别吐~ ~ ~):

file

从图中可以看到,椭圆可以被分成两条贝塞尔曲线,我们只需要找到对应的点即可。计算过程忽略,直接看代码(代码已经经过位置计算的优化,看上去更像使用鼠标点击的起始点到结束点的椭圆):

let k = ((x2 - x1) / 0.55);
let w = (x2 - x1) / 2;
let h = (y2 - y1) / 2;

// bezier double ellipse algorithm
context.moveTo(x1, y1 + h);
context.bezierCurveTo(x1, y1 + h * 3, x1 + w * 11 / 5, y1 + h * 3, x1 + w * 11 / 5, y1 + h);
context.bezierCurveTo(x1 + w * 11 / 5, y1 - h, x1, y1 - h, x1, y1 + h);
context.stroke();

效果:

这样就绘制出了一个比较完美的椭圆。

橡皮擦

在canvas中,有三个绘制图形函数,分别是fillRect()strokeRect()clearRect(),分别是填充图形,空心矩形,和清除矩形,前面两个函数我们已经使用过。最后的函数通常:

clearRect(0, 0, canvas.width, canvas.height)

可以完成清屏的功能。

我们如果想要达到橡皮擦的功能,该如何操作呢?

其实原理是一样的,只不过,我们需要先固定住我们需要修改的图片。

context.arc(x1, y1, 10, 0, 2 * Math.PI);  // 画一个圆形,位置即鼠标当前位置,大小就是橡皮擦的半径大小,当然,也可以不适用圆形,任意形状的橡皮擦都可以。
context.clip();  // 这句很重要,它可以将上面一句定义的形状,从当前画布中剪切出来单独操作,如果没有这一句,那么一会操作的仍然是整幅画布。
context.clearRect(0, 0, canvas.width, canvas.height);  // 这句很简单,和刚才的清空示例是一样的。
self.X1 = self.X2;
self.Y1 = self.Y2;

所以,它的整体逻辑分三步:

定义橡皮擦的大小和形状,通常我们定义为圆形。
固定画板,将橡皮擦的内容单独剪切出来。
清空剪切出来的内容,就完成了橡皮功能。

是不是很简单,当然,需要注意的是,随后不要忘记和随心画一样,实时修改传入的座标,达到连续擦出的效果。

这样,简单的橡皮功能也完成了。


完整的内容已经更新在了我的github - canvasPaint中,您也可以通过我的示例来测试一下功能。

前期目录:

JavaScript 之 canvas(一)-- 认识canvas
JavaScript 之 canvas(二)-- 绘制基本图形
JavaScript 之 canvas(三)-- 使用鼠标实时绘制图形
JavaScript 之 canvas(四)-- 绘制文字

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章