Canvas绘制带方向箭头需先计算单位方向向量(ux,uy)和垂直向量(vx,vy),再基于终点、headLen与angle确定箭头尖端、左侧点和右侧点坐标,最后用fill()绘制闭合三角形;极短线段需判空避免除零。

Canvas 中绘制带方向的箭头,关键在于根据起点和终点坐标计算出箭头头部的两个侧点——这需要向量运算和三角函数配合。不是简单画一条线再加个三角形,而是要让箭头始终“正对”线段方向,并随线段长度、粗细、角度自然缩放。
计算单位方向向量与垂直向量
给定起点 (x1, y1) 和终点 (x2, y2),先求方向向量:
dx = x2 - x1,dy = y2 - y1。
再归一化得单位方向向量:
len = Math.sqrt(dx*dx + dy*dy)(避免除零,len 接近 0 时跳过绘制)
ux = dx / len,uy = dy / len。
接着求单位垂直向量(左旋90°):
vx = -uy,vy = ux。
确定箭头头部三个顶点坐标
设箭头长度为 headLen(如 12),箭头张角一半为 angle(如 0.4 弧度),线宽为 lineWidth(影响箭头底边偏移):
- 箭头尖端:就是终点 (x2, y2)
- 左侧底点:从终点反向沿方向向量退 headLen,再向左垂直偏移 headLen × tan(angle)
- 右侧底点:同上,但向右偏移(即用 -vx, -vy)
更稳健的写法(考虑线宽居中):
- 箭头根部中心点:cx = x2 - ux * headLen,cy = y2 - uy * headLen
- 左侧点:lx = cx + vx * headLen * Math.tan(angle),ly = cy + vy * headLen * Math.tan(angle)
- 右侧点:rx = cx - vx * headLen * Math.tan(angle),ry = cy - vy * headLen * Math.tan(angle)
用 Canvas 路径绘制带箭头的线段
使用 ctx.beginPath() 连接四点构成封闭三角形(箭头)+ 主线段(可选):
- ctx.moveTo(x1, y1)
- ctx.lineTo(x2, y2)(主干,可 stroke)
- ctx.lineTo(lx, ly)
- ctx.lineTo(rx, ry)
- ctx.closePath()(闭合箭头三角形)
- ctx.fill() 填充箭头(推荐用 fillStyle,比 stroke 更稳)
若只要箭头不画主线,把前两步去掉,直接从 (x2,y2) → (lx,ly) → (rx,ry) → close。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
处理特殊情况与优化提示
实际项目中需注意:
- 当线段极短(len
- 箭头大小建议随 zoom 缩放,而非固定像素值
- 若流程图支持弯曲连接线(贝塞尔曲线),箭头方向应取曲线在终点处的切线方向,可用导数或差分近似
- 多个箭头重叠时,用 globalAlpha 或不同 fillStyle 区分层级,避免视觉粘连
数学方向控制的本质,是把几何意图翻译成向量操作——方向向量决定朝哪,垂直向量决定左右,三角函数决定张开幅度。写一次通用函数,后续所有流程图箭头都可复用。


















