如何在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
相关产品推荐
相关产品推荐

