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

如何在Canvas JS中绘制末端平滑收窄的尖头线条?

Canvas 绘制末端尖头平滑收窄线条的实现方法

不需要依赖arc方法拼接实现,有两种成熟方案可以按需选择:

方案1:主体等宽仅末端收窄(最简实现)

如果你的需求是线条主体宽度固定,仅末端需要收为尖头,直接在普通线条基础上补一个末端填充三角形即可,代码示例如下:

// 绘制主体线条
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(90, 4.5); // 预留出尖头的长度
ctx.stroke();

// 补全末端尖头
const tipLength = 10;
const dx = 100 - 90;
const dy = 5 - 4.5;
const verticalUnitX = -dy / tipLength;
const verticalUnitY = dx / tipLength;

ctx.beginPath();
ctx.moveTo(90 + verticalUnitX * 5, 4.5 + verticalUnitY * 5);
ctx.lineTo(100, 5);
ctx.lineTo(90 - verticalUnitX * 5, 4.5 - verticalUnitY * 5);
ctx.fill();

方案2:全段平滑收窄(从根部到尖头宽度渐变)

如果需要整条线条从粗到细平滑过渡,直接绘制自定义闭合路径填充即可,性能和实现复杂度都优于用arc拼接的方案,代码示例如下:

/**
 * 绘制锥形平滑收窄线条
 * @param {Object} ctx - canvas 上下文
 * @param {Number} x1 - 起点x坐标
 * @param {Number} y1 - 起点y坐标
 * @param {Number} x2 - 终点x坐标
 * @param {Number} y2 - 终点y坐标
 * @param {Number} startWidth - 起点线宽
 * @param {Number} endWidth - 终点线宽,要尖头设为0即可
 */
function drawTaperedLine(ctx, x1, y1, x2, y2, startWidth, endWidth = 0) {
  const dx = x2 - x1;
  const dy = y2 - y1;
  const lineLength = Math.hypot(dx, dy);
  // 计算线条垂直方向的单位向量,用来算上下边缘偏移
  const verticalUnitX = -dy / lineLength;
  const verticalUnitY = dx / lineLength;

  const halfStart = startWidth / 2;
  const halfEnd = endWidth / 2;

  ctx.beginPath();
  ctx.moveTo(x1 + verticalUnitX * halfStart, y1 + verticalUnitY * halfStart);
  ctx.lineTo(x2 + verticalUnitX * halfEnd, y2 + verticalUnitY * halfEnd);
  ctx.lineTo(x2 - verticalUnitX * halfEnd, y2 - verticalUnitY * halfEnd);
  ctx.lineTo(x1 - verticalUnitX * halfStart, y1 - verticalUnitY * halfStart);
  ctx.closePath();
  ctx.fill();
  // 如果需要边缘更柔和,可以加一行 ctx.filter = 'blur(0.5px)'; 模糊值按需调整
}

// 调用示例
drawTaperedLine(ctx, 0, 0, 100, 5, 10, 0);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:45:00