HTML canvas实现线矢量左右两侧绘制不同宽度单侧线条方案咨询
Canvas单侧扩展线条实现方案
核心原理
Canvas默认绘制线条时,lineWidth会沿路径两侧各扩展lineWidth/2的宽度。要实现仅单侧扩展,只需将原始路径沿非扩展侧的法线方向偏移lineWidth/2的距离后再绘制即可。
通用实现(支持任意角度线段)
偏移量计算逻辑
沿线段起点走向终点的方向,区分左右侧偏移:
- 计算线段方向向量:
dx = 终点x - 起点x,dy = 终点y - 起点y - 计算线段长度:
len = Math.sqrt(dx*dx + dy*dy) - 左侧单位法向量:
nx = -dy/len,ny = dx/len - 右侧单位法向量:
nx = dy/len,ny = -dx/len - 偏移后的坐标 = 原始坐标 + 法向量 * (线宽/2)
完整代码示例
const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); /** * 绘制单侧扩展线段 * @param {number} x1 原始线段起点x坐标 * @param {number} y1 原始线段起点y坐标 * @param {number} x2 原始线段终点x坐标 * @param {number} y2 原始线段终点y坐标 * @param {number} lineWidth 线条宽度 * @param {'left'|'right'} side 扩展方向(沿线段走向的左侧/右侧) * @param {string} color 线条颜色 */ function drawSingleSideLine(x1, y1, x2, y2, lineWidth, side, color) { const dx = x2 - x1; const dy = y2 - y1; const len = Math.sqrt(dx * dx + dy * dy); // 计算对应方向的单位法向量 const [nx, ny] = side === 'left' ? [-dy / len, dx / len] : [dy / len, -dx / len]; // 计算偏移后的坐标 const offset = lineWidth / 2; const offsetX1 = x1 + nx * offset; const offsetY1 = y1 + ny * offset; const offsetX2 = x2 + nx * offset; const offsetY2 = y2 + ny * offset; // 绘制线条 ctx.lineWidth = lineWidth; ctx.strokeStyle = color; ctx.beginPath(); ctx.moveTo(offsetX1, offsetY1); ctx.lineTo(offsetX2, offsetY2); ctx.stroke(); } // 测试用例:同一路径左侧画8px红色线,右侧画4px蓝色线 drawSingleSideLine(100, 100, 400, 200, 8, 'left', '#ff0000'); drawSingleSideLine(100, 100, 400, 200, 4, 'right', '#0000ff');
简化场景(水平/垂直线)
如果仅需要绘制水平或垂直线,可直接跳过向量计算,按方向直接偏移:
- 水平向右的线段:左侧扩展就将y坐标减
lineWidth/2,右侧扩展就将y坐标加lineWidth/2 - 垂直向下的线段:左侧扩展就将x坐标加
lineWidth/2,右侧扩展就将x坐标减lineWidth/2
内容的提问来源于stack exchange,提问作者Majid Hojati
相关产品推荐
相关产品推荐

