昨晚给开源项目 vue-fabric-editor 提交 PR,实现了细尾箭头绘制的功能,并被项目作者合并。今天就开一篇新的博客记录下绘制细尾箭头的实现经过。
实现的是鼠标拖拽绘制下图的这种箭头,和微信截图工具类似,鼠标按住就开始绘制,松开时绘制结束。
![12](/img/12.png)
一.已知条件
在 canvas 画布中绘制,已知条件是箭头的起始点坐标:A(x1, y1),B(x2, y2)
二.实现思路
先以(0, 0)为原点,绘制与 x 轴正方向平行的箭头,然后将画布平移并旋转,箭头的长度即为 AB 的长度。因此,需要计算得到旋转的角度以及 AB 的长度。
三.画出草图
假设箭头总长度是 length,计算得到箭头每个端点的坐标。草图如下图所示
![13](/img/13.png)
四.求出长度 length
首先求出坐标增量
1 | const xDiff = x2 - x1; |
然后根据坐标增量之和的平方根,求出 length
1 | const length = Math.hypot(xDiff, yDiff); |
五.求出旋转的坐标方位角
具体公式由来可以看底部的参考链接
1 | const angle = Math.atan2(yDiff, xDiff); |
六.最终的实现代码
画布偏移的值取(x1, y1)即可;先进行画布平移及旋转,然后通过绘制路径,将箭头绘制出来,填充颜色即可
1 | ctx.save(); |
七.在 fabric.js 中绘制
上面的代码是原生 canvas 的绘制方式,我给项目提的 PR 是用 fabric.js 实现的,与上述方式思路一致。
实现起来多了一些步骤,比如需要定义 fabricjs 的自定义子类,去继承原有的 fabric.line 元素,再用 canvas api 去绘制。
另外我也实现了拖动控制条改变箭头长宽时,箭头保持不变形的功能,感兴趣的可以查看我的 PR 详情:PR#382