如何让CSS @keyframes动画在指定关键帧处停止?
解决方案:无需重写动画,高效实现进度条停在指定百分比
不用非得用JS重写整个动画,有几个更高效的方案可以实现需求:
方案1:利用animation-delay负值直接跳转到目标进度
原动画总时长为5s,假设后端返回的目标进度为targetPercent(如30%),对应的时间点为5s * (targetPercent / 100)。给动画设置负的该延迟值,浏览器会直接从对应时间点的状态开始播放,配合forwards属性即可停在目标位置。
同时,原动画的颜色是随进度线性变化的,我们可以用CSS变量结合HSL颜色动态计算,摆脱预定义关键帧的限制:
修改后的CSS
.color-container { width: 100%; height: 200px; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; } .container { position: relative; width: 50%; border-radius: 4px; box-sizing: border-box; background: #fff; box-shadow: 0 10px 20px rgba(0, 0, 0, .5); } .Loading { position: relative; display: inline-block; width: 100%; height: 10px; background: #f1f1f1; box-shadow: inset 0 0 5px rgba(0, 0, 0, .2); border-radius: 4px; overflow: hidden; } .Loading:after { content: ''; position: absolute; left: 0; width: 0; height: 100%; border-radius: 4px; box-shadow: 0 0 5px rgba(0, 0, 0, .2); /* 用CSS变量动态计算颜色:从绿色到黄色的色相渐变 */ background: hsl(calc(80 - (var(--target-percent) * 0.2)), 80%, 50%); animation: load 5s forwards; } @keyframes load { 0% { width: 0%; } 100% { width: 100%; } }
JS控制代码
const targetPercent = 30; // 替换为后端返回的百分比 const loadingBar = document.querySelector('.Loading:after'); // 计算负延迟值 const delay = `-${5 * (targetPercent / 100)}s`; // 设置CSS变量和动画延迟 document.documentElement.style.setProperty('--target-percent', targetPercent); loadingBar.style.animationDelay = delay;
方案2:用transition替代@keyframes,直接控制最终状态
如果不需要原动画的逐帧颜色细节(或可通过动态计算实现),用过渡效果更简洁,完全不需要预定义关键帧:
修改后的CSS
.color-container { width: 100%; height: 200px; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; } .container { position: relative; width: 50%; border-radius: 4px; box-sizing: border-box; background: #fff; box-shadow: 0 10px 20px rgba(0, 0, 0, .5); } .Loading { position: relative; display: inline-block; width: 100%; height: 10px; background: #f1f1f1; box-shadow: inset 0 0 5px rgba(0, 0, 0, .2); border-radius: 4px; overflow: hidden; } .Loading:after { content: ''; position: absolute; left: 0; width: 0; height: 100%; border-radius: 4px; box-shadow: 0 0 5px rgba(0, 0, 0, .2); background: hsl(calc(80 - (var(--target-percent) * 0.2)), 80%, 50%); /* 过渡效果模拟原动画时长 */ transition: width 5s ease; }
JS控制代码
const targetPercent = 30; // 替换为后端返回的百分比 document.documentElement.style.setProperty('--target-percent', targetPercent); const loadingBar = document.querySelector('.Loading:after'); // 直接设置目标宽度 loadingBar.style.width = `${targetPercent}%`;
方案3:动态暂停动画(保留原逐帧颜色)
如果需要严格保留原动画的逐帧颜色变化,可以先启动动画,计算到目标进度的时间后暂停:
JS控制代码
const targetPercent = 30; // 替换为后端返回的百分比 const totalDuration = 5000; // 原动画总时长,单位毫秒 const loadingBar = document.querySelector('.Loading:after'); // 启动动画 loadingBar.style.animationPlayState = 'running'; // 计算到目标进度的时间,到时暂停 setTimeout(() => { loadingBar.style.animationPlayState = 'paused'; }, totalDuration * (targetPercent / 100));
总结:无需每次生成新的@keyframes文件,上述方案都能高效实现根据后端数据停在指定进度,其中方案1和方案2的灵活性、性能表现更优。
内容的提问来源于stack exchange,提问作者ufghd34
相关产品推荐
相关产品推荐

