SVG描边动画问题:如何实现节点与边缘间的流畅过渡?
解决SVG描边动画节点停顿问题
问题描述
SVG描边的dashoffset动画在路径节点处出现停顿,无法从节点到边缘流畅过渡。
核心原因
当前固定设置的stroke-dasharray: 30与路径实际总长度不匹配,导致动画循环时,虚线段在路径节点处无法连续衔接,产生停顿断层。
解决方案
1. 获取路径实际总长度
两种方式可选:
- JS动态计算:页面加载时获取路径总长度
const path = document.querySelector('.home-svg__1'); const totalLength = path.getTotalLength(); console.log(totalLength); // 输出路径实际长度(示例值为280) - SVG编辑器查看:用Figma、Illustrator或在线SVG编辑器打开文件,直接查看路径长度属性。
2. 调整stroke-dasharray参数
将stroke-dasharray设置为「可见线段长度 + 间隔线段长度」,两者之和需等于路径总长度,确保动画循环无缝衔接。例如路径总长度为280:
stroke-dasharray: 30 250; /* 30(可见段) + 250(间隔段) = 280(路径总长度) */
3. 修正动画的stroke-dashoffset终点值
动画终点的stroke-dashoffset需与路径总长度一致,保证首尾衔接无停顿:
@keyframes home-svg { 0% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 280; /* 等于路径总长度 */ } }
4. 可选优化:避免缩放影响描边
添加vector-effect: non-scaling-stroke,确保SVG缩放时描边宽度稳定,动画不受干扰:
.home-svg .stroke-anim { vector-effect: non-scaling-stroke; }
修改后的完整代码
CSS部分
:root { --c3: #ffffff; --c6: #68b6c8; } body { background: linear-gradient(90deg, #0a0427, #1a0083); } .home-svg { width: 80vw; height: 50vh; fill: transparent; transition: all 0.5s cubic-bezier(0.6, 0.38, 0.29, 0.92) 0.5s, transform 1s cubic-bezier(0.6, 0.38, 0.29, 0.92) 0s; } @media screen and (min-width: 1000px), screen and (max-width: 999px) { .home-svg { position: absolute; top: calc(50% + (var(--offset) * 3)); left: -30%; transform: translate(50%, 50%); z-index: -1; } } .home-svg .stroke { stroke: rgba(255, 255, 255, 0.1); stroke-width: 0.25px; } @media screen and (max-width: 999px) { .home-svg .stroke { stroke: rgba(255, 255, 255, 0.3); stroke-width: 0.4px; } } .home-svg .stroke-anim { stroke: var(--c3); stroke-width: 0.4px; stroke-dasharray: 30 250; /* 匹配路径总长度280 */ vector-effect: non-scaling-stroke; animation: home-svg linear 12s infinite; } @media screen and (max-width: 999px) { .home-svg .stroke-anim { stroke-width: 0.4px; } } .home-svg .stroke-anim .home-svg__2, .home-svg .stroke-anim .home-svg__4 { stroke: var(--c6); } @keyframes home-svg { 0% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 280; /* 等于路径总长度 */ } }
HTML部分
<svg class="home-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 177.906 50"> <g class="stroke"> <path class="home-svg__1" d="M33.5491 50l13.9965 0 -15.3458 -50 -16.7217 0.0001 -15.4781 49.9999 14.1287 0c2.9104,-12.9287 6.2177,-25.6941 9.3663,-38.5683l0.6879 0.0001c3.1485,12.9558 6.4558,25.6395 9.3662,38.5682l0 0z" /> </g> <g class="stroke-anim"> <path class="home-svg__1" d="M33.5491 50l13.9965 0 -15.3458 -50 -16.7217 0.0001 -15.4781 49.9999 14.1287 0c2.9104,-12.9287 6.2177,-25.6941 9.3663,-38.5683l0.6879 0.0001c3.1485,12.9558 6.4558,25.6395 9.3662,38.5682l0 0z" /> </g> </svg>
动态计算路径长度的JS(可选)
window.addEventListener('load', () => { const path = document.querySelector('.home-svg__1'); const totalLength = path.getTotalLength(); const strokeAnim = document.querySelector('.stroke-anim'); // 动态设置dasharray strokeAnim.style.strokeDasharray = `30 ${totalLength - 30}`; // 动态生成动画关键帧 const style = document.createElement('style'); style.textContent = ` @keyframes home-svg { 0% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: ${totalLength}; } } `; document.head.appendChild(style); });
内容的提问来源于stack exchange,提问作者fegon
相关产品推荐
相关产品推荐

