SVG多动画技术问询:藏宝图路径动画中浅灰虚线随黑色填充消失问题
解决藏宝图SVG路径动画同步隐藏问题
嘿,我明白你想实现的效果:当黑色的.road路径逐渐绘制出来时,下方的浅灰色.steps虚线会跟着被覆盖,要么消失要么变成黑色。咱们先看看原代码里的问题,再一步步修正它。
原代码的核心问题
.steps的stroke-dasharray设为-744是无效的,这个属性只能用正数定义虚线的段长和间距draw-steps动画的逻辑不对,反向动画并不能实现和.road同步的覆盖效果- 两个动画的时长虽然都是10s,但没有设置
animation-timing-function保证同步,起始状态也没对齐
方案1:用反向Dash动画实现.steps随绘制消失
这个方法是让.steps的虚线动画和.road完全反向,当.road往前绘制时,.steps的虚线往后“收缩”,看起来就像是被覆盖消失了。我们还可以在动画里同步改变.steps的颜色,让它被覆盖时变成黑色。
修正后的完整代码如下:
<style> svg { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; } .road { stroke-dasharray: 744; stroke-dashoffset: 744; /* 初始状态完全隐藏 */ animation: draw-road 10s linear infinite; } .steps { stroke-dasharray: 744; /* 和road保持相同的总长度 */ stroke-dashoffset: 0; /* 初始状态完全显示 */ animation: draw-steps 10s linear infinite; } @keyframes draw-road { 0% { stroke-dashoffset: 744; stroke: #000000; } 100% { stroke-dashoffset: 0; stroke: #000000; } } @keyframes draw-steps { 0% { stroke-dashoffset: 0; stroke: #999; /* 初始浅灰色 */ } 100% { stroke-dashoffset: 744; /* 完全隐藏 */ stroke: #000; /* 最后变成黑色,和road一致 */ } } </style> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> <style> .st0{fill:none;stroke:#999;stroke-width:2;stroke-miterlimit:10} .st2{fill:#b3b3b3} </style> <g id="Layer_1"> <path class="st0" d="M20.82 225.01c1.05-1.32 2.08-2.63 3.1-3.92"/> <path d="M30.16 213.14c47.85-61.32 61-85.9 56.16-90.62-7.14-6.97-60.04 22.79-57 46 2.94 22.48 115.32-.75 124 27 3.14 10.05-9.18 19.09-5 25 8.54 12.09 73.6-6.39 76-30 3.26-32.1-111.39-53.93-109-82 1.2-14.1 32-30.41 153.49-42.53" fill="none" class="road" stroke="#999" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="10.1073,10.1073"/> <path class="st0" d="M20.82 225.01c1.05-1.32 2.08-2.63 3.1-3.92"/> <path d="M30.16 213.14c47.85-61.32 61-85.9 56.16-90.62-7.14-6.97-60.04 22.79-57 46 2.94 22.48 115.32-.75 124 27 3.14 10.05-9.18 19.09-5 25 8.54 12.09 73.6-6.39 76-30 3.26-32.1-111.39-53.93-109-82 1.2-14.1 32-30.41 153.49-42.53" fill="none" stroke="#999" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="10.1073,10.1073" class="steps"/> <path class="st0" d="M273.84 65.49c1.64-.16 3.3-.32 4.98-.48"/> <path class="st2" d="M55.96 140.02l-3.27-4.42-4.42 3.27-1.79-2.41 4.42-3.27-3.27-4.42 2.41-1.79 3.27 4.42 4.42-3.27 1.79 2.41-4.42 3.27 3.27 4.42-2.41 1.79zM158 200.86l-4.29-3.44-3.44 4.29-2.34-1.88 3.44-4.29-4.29-3.44 1.88-2.34 4.29 3.44 3.44-4.29 2.34 1.88-3.44 4.29 4.29 3.44-1.88 2.34zM149 140.86l-4.29-3.44-3.44 4.29-2.34-1.88 3.44-4.29-4.29-3.44 1.88-2.34 4.29 3.44 3.44-4.29 2.34 1.88-3.44 4.29 4.29 3.44-1.88 2.34zM212 78.86l-4.29-3.44-3.44 4.29-2.34-1.88 3.44-4.29-4.29-3.44 1.88-2.34 4.29 3.44 3.44-4.29 2.34 1.88-3.44 4.29 4.29 3.44-1.88 2.34z"/> </g> </svg>
关键修改点说明
- 给两个动画都加上
linear计时函数,保证动画速度全程一致,不会出现不同步的情况 .steps的stroke-dasharray改为和.road相同的744,确保总长度匹配draw-steps动画从stroke-dashoffset: 0(完全显示)过渡到stroke-dashoffset: 744(完全隐藏),和draw-road的动画方向完全相反- 在
draw-steps动画里同步修改stroke颜色,让它随着绘制逐渐从浅灰变成黑色,和.road融合
方案2:用SVG Mask实现精准覆盖(更推荐)
如果想要更精准的“覆盖”效果——就是.road绘制到哪里,哪里的.steps就被完全遮挡,可以用SVG的mask功能。这个方法逻辑更清晰,效果也更稳定:
<style> svg { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; } .road { stroke-dasharray: 744; stroke-dashoffset: 744; animation: draw-road 10s linear infinite; } .mask-path { stroke-dasharray: 744; stroke-dashoffset: 744; animation: draw-road 10s linear infinite; } @keyframes draw-road { 0% { stroke-dashoffset: 744; } 100% { stroke-dashoffset: 0; } } </style> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> <defs> <!-- 创建一个遮罩:未绘制的部分显示,已绘制的部分隐藏 --> <mask id="road-mask"> <rect width="100%" height="100%" fill="white"/> <path d="M30.16 213.14c47.85-61.32 61-85.9 56.16-90.62-7.14-6.97-60.04 22.79-57 46 2.94 22.48 115.32-.75 124 27 3.14 10.05-9.18 19.09-5 25 8.54 12.09 73.6-6.39 76-30 3.26-32.1-111.39-53.93-109-82 1.2-14.1 32-30.41 153.49-42.53" fill="none" class="mask-path" stroke="black" stroke-width="2" stroke-miterlimit="10"/> </mask> </defs> <style> .st0{fill:none;stroke:#999;stroke-width:2;stroke-miterlimit:10} .st2{fill:#b3b3b3} </style> <g id="Layer_1"> <path class="st0" d="M20.82 225.01c1.05-1.32 2.08-2.63 3.1-3.92"/> <!-- 浅灰色steps路径,应用遮罩 --> <path d="M30.16 213.14c47.85-61.32 61-85.9 56.16-90.62-7.14-6.97-60.04 22.79-57 46 2.94 22.48 115.32-.75 124 27 3.14 10.05-9.18 19.09-5 25 8.54 12.09 73.6-6.39 76-30 3.26-32.1-111.39-53.93-109-82 1.2-14.1 32-30.41 153.49-42.53" fill="none" stroke="#999" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="10.1073,10.1073" mask="url(#road-mask)"/> <!-- 黑色road路径在上方 --> <path d="M30.16 213.14c47.85-61.32 61-85.9 56.16-90.62-7.14-6.97-60.04 22.79-57 46 2.94 22.48 115.32-.75 124 27 3.14 10.05-9.18 19.09-5 25 8.54 12.09 73.6-6.39 76-30 3.26-32.1-111.39-53.93-109-82 1.2-14.1 32-30.41 153.49-42.53" fill="none" class="road" stroke="#000" stroke-width="2" stroke-miterlimit="10"/> <path class="st0" d="M20.82 225.01c1.05-1.32 2.08-2.63 3.1-3.92"/> <path class="st0" d="M273.84 65.49c1.64-.16 3.3-.32 4.98-.48"/> <path class="st2" d="M55.96 140.02l-3.27-4.42-4.42 3.27-1.79-2.41 4.42-3.27-3.27-4.42 2.41-1.79 3.27 4.42 4.42-3.27 1.79 2.41-4.42 3.27 3.27 4.42-2.41 1.79zM158 200.86l-4.29-3.44-3.44 4.29-2.34-1.88 3.44-4.29-4.29-3.44 1.88-2.34 4.29 3.44 3.44-4.29 2.34 1.88-3.44 4.29 4.29 3.44-1.88 2.34zM149 140.86l-4.29-3.44-3.44 4.29-2.34-1.88 3.44-4.29-4.29-3.44 1.88-2.34 4.29 3.44 3.44-4.29 2.34 1.88-3.44 4.29 4.29 3.44-1.88 2.34zM212 78.86l-4.29-3.44-3.44 4.29-2.34-1.88 3.44-4.29-4.29-3.44 1.88-2.34 4.29 3.44 3.44-4.29 2.34 1.88-3.44 4.29 4.29 3.44-1.88 2.34z"/> </g> </svg>
Mask方案的逻辑
- 创建一个遮罩,里面的白色矩形是默认显示区域,黑色路径是要隐藏的区域
- 遮罩里的黑色路径和
.road用完全相同的动画,随着动画推进,遮罩会逐渐隐藏.steps中被.road覆盖的部分 .steps在下方,.road在上方,这样看起来就是.road绘制到哪里,哪里
相关产品推荐
相关产品推荐

