HTML5 中的 Canvas arcTo vs SVG ArcTo

在 HTML5 中,要搞出来一段弧线,有 2 中方式:使用 Canvas 的 arcTo 或者使用 SVG 的 path 元素。这两者都有 ArcTo 的概念,但是他们之中的 ArcTo 的差异还是很大的。

Canvas arcTo 函数

在 Canvas 中,arcTo 是最容易引起误解的一个函数,因为他的名字、参数以及输出完全不符合常规逻辑。但是一旦你理解了,就能够很准确的使用这个函数了。

下面是一个交互演示,让我们来认识一下 Canvas 中的 arcTo 函数是如何工作的。

<script>
    context.beginPath();
    context.moveTo(100, 225);// P0
    context.arcTo(300, 25, 500, 225, 75);// P1, P2 and the radius
    context.lineTo(500,225);// P2
    context.stroke();
</script>

[您的浏览器不支持 Canvas,换一个高端浏览器试试吧]

Canvas 中的 arcTo 是如何工作的?

在 arcTo 函数中,虽然参数只涉及到 P1 和 P2 两个点,实际上还有一个隐含的点,就是画布上的当前点(P0)。当 P0, P1, P2 不重叠也不在一条直线的时候,这 3 个点可以构成一个三角形。想象一下,从 P0 开始,向 P1 画一条线段,从 P1 开始到 P2 再画一条线段,这两条线段形成一个夹角,然后以 r 画一个圆,移动这个圆将这个圆与线段 P0P1 和线段 P1P2 相切(也可能切点是在 P0P1 或者 P1P2 的延长线上),然后保留朝向 P1 这个点的弧线,就是 arcTo 在弧线这部分做的事情。下图可能解释的更加清晰:

arcto-example
整个步骤是这样的:

  1. moveTo 给出 P0 点坐标
  2. arcTo 函数中的参数给出了 P1 点和 P2 点的坐标,以及圆形的半径 r
  3. 计算以 r 为半径的圆和直线 P0P1 以及 P1P2 的切点,记为 S 点和 E 点,对应图上 Start 和 End 两个点
  4. 从 P0 向 S 点画出一条线段
  5. 从 S 点到 E 点,画出一段圆弧,半径为 r
  6. 此时,画布当前点为 E 点
  7. 然后从 E 点又画了一条线段到 P2 点,至此 arcTo 的工作已经完成,接下来你可以 stroke 或者 fill 了

SVG 中的 ArcTo

在 SVG 中,ArcTo 是 path 元素中的一个指令。path 元素的 d 属性为一个字符串,表示这个路径的过程。
d 属性中的指令有:

  1. Moveto,移动。大写的 M 表示绝对坐标,小写的 m 表示移动相对坐标
  2. Lineto,画直线。类似的,大写的 L 表示直线目标点的绝对坐标,小写的 l 表示目标点的相对坐标
  3. Curveto,贝塞尔曲线
  4. Arcto,椭圆形曲线,当横向和纵向半径相等的时候,就是圆形曲线了

对于 Arcto 指令,它的参数比较多:

其中:

  • A – 椭圆形曲线指令
  • rx, ry – 椭圆形的长半径和短半径。我们为了画出圆形的曲线,所以,设置 rx 和 ry 相等,就是我们要画的圆弧的半径
  • xAxisRotate – 暂时忽略此参数
  • LargeArcFlag – 可选值为 0 或者 1,表示画出大圆弧还是小圆弧。我们知道,给出不重叠的 2 个点以及半径,可以画出 2 种圆弧,一个大,一个小。详见下图
  • SweepFlag – 可选值为 0 或者 1,0 表示逆时针画,1 表示顺时针画
  • x, y – 目标点坐标
大弧线和小弧线演示,下图中,给定 P1 和 P2 和半径 r,画出一条圆弧,有 2 种画法,绿色的表示大弧线(LargeArcFlag 参数为 1),红色的表示小弧线(LargeArcFlag 参数为 0)。
 
可以看出来,SVG 中的 arcTo 只涉及到 2 个点:起始点和终止点,然后再指定半径,就可以画出来圆弧了。由于只有 2 个点,所以还需要控制大圆弧还是小圆弧。
需要注意的是,当在 SVG 中的 path 元素使用 ArcTo 的时候,弧线的起始点和终止点不能重叠,否则将画不出来这个 path。

4 Comments

  • 码农 回复

    写的不错

  • www.yzc666.com 回复

    通过云端的道路,只亲吻攀登者的足迹。

  • www.bst316.com 回复

    事常与人违,事总在人为。

  • 高阳毛巾网 回复

    来看看

发表评论

电子邮件地址不会被公开。 必填项已用*标注