能否实现描边时长与路径长度无关的SVG描边动画?
解决SVG不同路径描边动画等时长问题
问题分析
- 当前使用固定像素值
stroke-dasharray: 2000,小图形的路径长度远小于2000,因此动画完成速度更快; - 设置
stroke-dasharray: 100%无效,是因为SVG中该属性的百分比是相对于SVG视口尺寸,而非路径自身的实际长度,无法匹配路径完整长度。
解决方案
要实现不同路径的描边动画时长一致,需要让stroke-dasharray和stroke-dashoffset匹配每个路径的真实长度,以下是两种可行方法:
方法1:CSS变量+JS动态计算路径长度
通过JS获取每个图形的路径长度,赋值给CSS变量,再在动画中引用该变量,确保动画参数与路径长度完全匹配。
修改后的完整代码:
.page-wrapper { display: flex; justify-content: center; align-items: center; gap: 2em; } .radar-wrapper { width: 300px; height: 300px; } .shape { fill: #ff4040; fill-opacity: .4; stroke: #ff4040; stroke-width: 2; stroke-dasharray: var(--path-length); stroke-dashoffset: var(--path-length); animation: draw 5s infinite linear; } @keyframes draw { to { stroke-dashoffset: 0; } }
<div class="page-wrapper"> <div class="radar-wrapper"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> <polygon class="shape" points="116.67 3.97 155.96 123.88 243.39 32.89 174.14 138.38 299.79 150 174.14 161.62 243.39 267.11 155.96 176.12 116.67 296.03 133.3 170.95 15.05 214.99 123.21 150 15.05 85.01 133.3 129.05 116.67 3.975"></polygon> </svg> </div> <div class="radar-wrapper"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> <polygon class="shape" points="144.04 176.12 133.3 170.95 125.86 161.62 123.21 150 125.86 138.38 133.3 129.05 144.04 123.88 155.96 123.88 166.7 129.05 174.14 138.38 176.79 150 174.14 161.62 166.7 170.95 155.96 176.12 144.04 176.12"></polygon> </svg> </div> </div> <script> document.querySelectorAll('.shape').forEach(shape => { const pathLength = shape.getTotalLength(); shape.style.setProperty('--path-length', pathLength); }); </script>
方法2:SVG原生pathLength属性
给每个<polygon>添加pathLength="1"属性,将所有路径的长度归一为1,此时用stroke-dasharray: 1即可适配所有路径,无需JS介入。
修改后的SVG与CSS:
<!-- 给每个polygon添加pathLength属性 --> <polygon class="shape" pathLength="1" points="..."></polygon>
.shape { /* 其他样式不变 */ stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw 5s infinite linear; } @keyframes draw { to { stroke-dashoffset: 0; } }
关键说明
SVG规范中,stroke-dasharray的百分比值是基于视口的宽/高(取决于路径走向),而非路径自身长度,所以无法用来匹配不同路径的真实长度,这就是设置100%后描边无法覆盖完整路径的原因。
内容的提问来源于stack exchange,提问作者marklovin
相关产品推荐
相关产品推荐

