使用jQuery修改CSS动画速度时遇SVG跳转问题
解决SVG动画时长动态修改时的跳转问题
问题核心:直接修改CSS动画的animation-duration会导致动画重置到起始帧,产生跳转。要让动画平滑过渡速度,需要在修改时长时保留当前动画进度,通过调整animation-delay来补偿。
修改后的实现代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container"> <section> <div id="figure" class="fig"> <svg height="50" width="800"> <line class="sleeve" x1="0" y1="20" x2="800" y2="20" style="stroke:rgb(255,0,0);stroke-width:2" /> </svg> </div> </section> <input type="number" id="sp" min="0.1" max="2" step="0.1" value="0.1"> </div>
CSS
@keyframes flow { 0% { stroke-dashoffset: 55px; } 100% { stroke-dashoffset: 0px; } } #figure svg { animation: fadeopacity 1s 0.5s both; } #figure svg .sleeve { stroke-width: 3; stroke-dasharray: 50px 5px; fill: none; color: #4792da; stroke: currentColor; animation-name: flow; animation-duration: 1s; animation-iteration-count: infinite; animation-timing-function: linear; animation-play-state: running; }
JavaScript
const inputElement = document.getElementById('sp'); const sleeveEl = $("#figure svg .sleeve")[0]; let lastDuration = parseFloat(getComputedStyle(sleeveEl).animationDuration); let lastTime = performance.now(); inputElement.addEventListener('input', function() { const newDuration = parseFloat(this.value); if (isNaN(newDuration) || newDuration <= 0) return; // 计算当前动画已运行的时间 const currentTime = performance.now(); const elapsedTime = (currentTime - lastTime) / 1000; // 计算当前进度(0-1之间) const progress = (elapsedTime % lastDuration) / lastDuration; // 新的延迟:让动画从当前进度继续,负数延迟表示直接跳到对应进度 const newDelay = -progress * newDuration; // 更新动画属性 sleeveEl.style.animationDuration = `${newDuration}s`; sleeveEl.style.animationDelay = `${newDelay}s`; // 更新记录的时长和时间 lastDuration = newDuration; lastTime = currentTime; });
原理说明
- 每次修改时长前,记录当前时间和上一次的动画时长,计算出动画已经运行的时间和当前进度
- 通过设置负的
animation-delay,让动画直接跳到当前进度对应的位置,而不是从起始帧开始 - 这样修改时长后,动画会从当前视觉位置继续平滑播放,不会出现跳转
内容的提问来源于stack exchange,提问作者Tarık Öztürk
相关产品推荐
相关产品推荐

