You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何通过Canvas绘制带箭头的线段

Canvas线段添加箭头实现方法

箭头线段效果示例

实现原理

原生Canvas 2D上下文没有内置线段箭头样式,实现逻辑如下:

  • 先调用原生线段绘制API,画出两点之间的主线段
  • 通过三角函数计算线段的倾斜角度,推导箭头三角形另外两个顶点的坐标
  • 在对应端点填充(或描边)三角形箭头,和主线段自然衔接即可

可复用封装代码

直接封装通用绘制函数,支持自定义箭头大小、颜色、单/双端箭头等配置:

/**
 * 绘制带箭头的线段
 * @param {CanvasRenderingContext2D} ctx canvas 2D上下文
 * @param {number} x1 起点X坐标
 * @param {number} y1 起点Y坐标
 * @param {number} x2 终点X坐标
 * @param {number} y2 终点Y坐标
 * @param {object} options 样式配置
 */
function drawArrowLine(ctx, x1, y1, x2, y2, options = {}) {
  // 默认配置
  const config = {
    lineWidth: 2,
    strokeStyle: '#000000',
    fillStyle: '#000000',
    arrowSize: 10, // 箭头侧边长度
    arrowAngle: Math.PI / 6, // 箭头侧边与主线段夹角,默认30度
    hasStartArrow: false, // 起点是否显示箭头
    hasEndArrow: true // 终点是否显示箭头
  }
  Object.assign(config, options)

  ctx.save()
  // 绘制主线段
  ctx.lineWidth = config.lineWidth
  ctx.strokeStyle = config.strokeStyle
  ctx.fillStyle = config.fillStyle
  ctx.beginPath()
  ctx.moveTo(x1, y1)
  ctx.lineTo(x2, y2)
  ctx.stroke()

  // 计算主线段倾斜弧度
  const lineSlope = Math.atan2(y2 - y1, x2 - x1)

  // 单箭头绘制逻辑
  const drawArrow = (tipX, tipY, directionRadian) => {
    // 计算箭头两个底角坐标
    const p1X = tipX - config.arrowSize * Math.cos(directionRadian - config.arrowAngle)
    const p1Y = tipY - config.arrowSize * Math.sin(directionRadian - config.arrowAngle)
    const p2X = tipX - config.arrowSize * Math.cos(directionRadian + config.arrowAngle)
    const p2Y = tipY - config.arrowSize * Math.sin(directionRadian + config.arrowAngle)

    ctx.beginPath()
    ctx.moveTo(tipX, tipY)
    ctx.lineTo(p1X, p1Y)
    ctx.lineTo(p2X, p2Y)
    ctx.closePath()
    ctx.fill()
  }

  // 按配置绘制两端箭头
  if (config.hasEndArrow) drawArrow(x2, y2, lineSlope)
  if (config.hasStartArrow) drawArrow(x1, y1, lineSlope + Math.PI)

  ctx.restore()
}

使用方式

获取canvas上下文后直接调用函数即可:

const canvas = document.getElementById('yourCanvas')
const ctx = canvas.getContext('2d')

// 绘制默认样式的单端箭头线段
drawArrowLine(ctx, 50, 50, 220, 160)

// 绘制双端蓝色箭头线段,自定义箭头大小
drawArrowLine(ctx, 50, 220, 280, 220, {
  strokeStyle: '#2563eb',
  fillStyle: '#2563eb',
  arrowSize: 14,
  hasStartArrow: true
})

自定义调整说明

  • 调整arrowAngle参数可以改变箭头尖锐度:数值越小箭头越尖,数值越大箭头越宽
  • 如果需要空心箭头,把箭头绘制逻辑里的ctx.fill()替换为ctx.stroke()即可,注意同步配置描边样式
  • 如果画布存在缩放、平移变换,箭头大小需要同步乘上当前缩放比例,避免箭头大小失真

内容的提问来源于stack exchange,提问作者Kevin Yang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:15:43