如何编程控制SVG圆弧描边的长度与显示范围?
实现SVG圆弧描边的起止长度控制
我在Inkscape中创建了一个圆形,关闭填充仅保留描边可见,并将圆弧起点设为45°、终点设为315°。随后将其旋转90°,得到如下SVG代码:
<?xml version="1.0" encoding="UTF-8"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg width="300" height="300" version="1.1" viewBox="0 0 79.375 79.375" xmlns="http://www.w3.org/2000/svg"> <path transform="rotate(90)" d="m64.961-15.355a34.984 34.412 0 0 1-49.474 1e-6 34.984 34.412 0 0 1-1e-6 -48.666 34.984 34.412 0 0 1 49.474-2e-6" fill="none" opacity=".55814" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10.583"/> </svg>
该代码渲染效果如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg width="300" height="300" version="1.1" viewBox="0 0 79.375 79.375" xmlns="http://www.w3.org/2000/svg"> <path transform="rotate(90)" d="m64.961-15.355a34.984 34.412 0 0 1-49.474 1e-6 34.984 34.412 0 0 1-1e-6 -48.666 34.984 34.412 0 0 1 49.474-2e-6" fill="none" opacity=".55814" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10.583"/> </svg>
我希望叠加一个该图形的副本,并从左下角起点控制描边长度,例如仅显示副本总长度的22%,或显示从315°终点到255.60°的线段。请问如何通过编程实现类似Inkscape的起止点控制功能?
解决方案
方法一:用stroke-dasharray和stroke-dashoffset快速控制(无需修改路径)
这种方法不用重新生成路径,直接通过描边的虚线参数控制显示范围,适合按比例或长度控制:
- 获取路径总长度:用SVG原生方法
getTotalLength()可以拿到路径的实际像素长度,记为totalLength。 - 设置虚线参数:
- 要显示22%的长度:
stroke-dasharray设为[totalLength*0.22, totalLength],表示“显示段长度,隐藏段长度”;因为要从左下角起点(原路径的终点方向)开始显示,stroke-dashoffset设为totalLength*(1-0.22),把显示段偏移到目标起点位置。 - 对应角度需求:原圆弧总角度是270°(315°-45°),315°到255.60°的角度差是59.4°,比例正好是22%,所以参数和上面一致。
- 要显示22%的长度:
静态SVG示例:
<?xml version="1.0" encoding="UTF-8"?> <svg width="300" height="300" version="1.1" viewBox="0 0 79.375 79.375" xmlns="http://www.w3.org/2000/svg"> <!-- 原半透明图形 --> <path transform="rotate(90)" d="m64.961-15.355a34.984 34.412 0 0 1-49.474 1e-6 34.984 34.412 0 0 1-1e-6 -48.666 34.984 34.412 0 0 1 49.474-2e-6" fill="none" opacity=".55814" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10.583"/> <!-- 红色的22%长度副本(从左下角起点开始) --> <path transform="rotate(90)" d="m64.961-15.355a34.984 34.412 0 0 1-49.474 1e-6 34.984 34.412 0 0 1-1e-6 -48.666 34.984 34.412 0 0 1 49.474-2e-6" fill="none" stroke="#f00" stroke-linecap="round" stroke-linejoin="round" stroke-width="10.583" stroke-dasharray="25.96 118.0" stroke-dashoffset="92.04"/> </svg>
动态计算的JS代码:
// 获取目标路径元素 const pathCopy = document.querySelector('.path-copy'); const totalLength = pathCopy.getTotalLength(); const displayRatio = 0.22; const displayLength = totalLength * displayRatio; // 设置描边参数 pathCopy.setAttribute('stroke-dasharray', `${displayLength} ${totalLength}`); pathCopy.setAttribute('stroke-dashoffset', totalLength - displayLength);
方法二:重新生成目标路径(精确角度控制)
如果需要严格按角度范围生成路径,可以解析原圆弧参数,计算目标角度对应的坐标,生成新路径:
- 解析原圆弧参数:原路径的
d属性中,a34.984 34.412是椭圆的x/y半径(近似圆形),旋转90°后,原圆弧的起点45°变为135°,终点315°变为45°,左下角起点对应原终点315°旋转后为225°。 - 计算目标坐标:以viewBox中心(39.6875, 39.6875)为圆心,用三角函数计算225°和255.60°+90°=345.6°对应的坐标,然后生成圆弧路径。
示例SVG代码:
<?xml version="1.0" encoding="UTF-8"?> <svg width="300" height="300" version="1.1" viewBox="0 0 79.375 79.375" xmlns="http://www.w3.org/2000/svg"> <!-- 原半透明图形 --> <path transform="rotate(90)" d="m64.961-15.355a34.984 34.412 0 0 1-49.474 1e-6 34.984 34.412 0 0 1-1e-6 -48.666 34.984 34.412 0 0 1 49.474-2e-6" fill="none" opacity=".55814" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10.583"/> <!-- 精确角度控制的红色副本 --> <path transform="rotate(90)" d="m15.487,-64.817 a34.984 34.412 0 0 1 31.38, -13.57" fill="none" stroke="#f00" stroke-linecap="round" stroke-linejoin="round" stroke-width="10.583"/> </svg>
内容的提问来源于stack exchange,提问作者Ole
相关产品推荐
相关产品推荐

