如何在任意角度的SVG线段中点添加两条垂直于主线的交叉短线?
SVG 主线段中点断线效果实现方案
核心实现逻辑
- 读取主线段两个端点坐标
(x1,y1)、(x2,y2),计算中点坐标midX = (x1+x2)/2、midY = (y1+y2)/2 - 计算主线段倾斜角度
angle = Math.atan2(y2-y1, x2-x1),其垂直方向角度为angle + Math.PI/2 - 以中点为基准,沿主线走向分别向前后偏移固定距离,在两个偏移点上分别绘制垂直于主线的短线,即可得到交叉断线效果
- 若需要断开主线中点位置,可通过SVG掩码功能遮盖中点区域的线段
可运行代码示例
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg"> <!-- 示例主线段,可替换为用户绘制的任意线段 --> <line id="mainLine" x1="50" y1="70" x2="350" y2="220" stroke="black" stroke-width="2"/> <script type="text/javascript"><![CDATA[ const mainLine = document.getElementById('mainLine'); // 读取主线段端点坐标 const x1 = parseFloat(mainLine.getAttribute('x1')); const y1 = parseFloat(mainLine.getAttribute('y1')); const x2 = parseFloat(mainLine.getAttribute('x2')); const y2 = parseFloat(mainLine.getAttribute('y2')); // 计算基础参数 const midX = (x1 + x2) / 2; const midY = (y1 + y2) / 2; const angle = Math.atan2(y2 - y1, x2 - x1); // 自定义配置参数 const shortLineLength = 8; // 交叉短线长度 const gap = 2; // 两条短线之间的间距,同时也是主线断开的宽度 // 生成两条垂直短线 for (let offsetDir of [-1, 1]) { const offsetX = Math.cos(angle) * gap * offsetDir; const offsetY = Math.sin(angle) * gap * offsetDir; const lineX1 = midX + offsetX + Math.cos(angle + Math.PI / 2) * shortLineLength / 2; const lineY1 = midY + offsetY + Math.sin(angle + Math.PI / 2) * shortLineLength / 2; const lineX2 = midX + offsetX - Math.cos(angle + Math.PI / 2) * shortLineLength / 2; const lineY2 = midY + offsetY - Math.sin(angle + Math.PI / 2) * shortLineLength / 2; const shortLine = document.createElementNS('http://www.w3.org/2000/svg', 'line'); shortLine.setAttribute('x1', lineX1); shortLine.setAttribute('y1', lineY1); shortLine.setAttribute('x2', lineX2); shortLine.setAttribute('y2', lineY2); shortLine.setAttribute('stroke', 'black'); shortLine.setAttribute('stroke-width', '2'); mainLine.parentNode.appendChild(shortLine); } // 开启以下代码可实现主线中点断开效果 // const mask = document.createElementNS('http://www.w3.org/2000/svg', 'mask'); // mask.id = 'breakMask'; // const bg = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); // bg.setAttribute('width', '100%'); // bg.setAttribute('height', '100%'); // bg.setAttribute('fill', 'white'); // const cover = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); // cover.setAttribute('x', midX - gap * 1.2); // cover.setAttribute('y', midY - 10); // cover.setAttribute('width', gap * 2.4); // cover.setAttribute('height', 20); // cover.setAttribute('fill', 'black'); // mask.appendChild(bg); // mask.appendChild(cover); // mainLine.parentNode.appendChild(mask); // mainLine.setAttribute('mask', 'url(#breakMask)'); ]]></script> </svg>
参数调整说明
- 修改
shortLineLength可调整交叉短线的长度,适配不同粗细的主线 - 修改
gap可调整两条短线之间的间距,同时决定主线断开的宽度 - 不需要主线断开时,直接注释掉掩码相关的代码块即可保留完整主线
内容的提问来源于stack exchange,提问作者João Durante
相关产品推荐
相关产品推荐

