如何使用计算值作为CSS @keyframes动画的关键帧实现60分钟周期动画
实现列车60分钟周期运行动画的解决方案
核心问题说明:原生CSS不支持在@keyframes的关键帧百分比位置直接写入算术表达式,必须使用计算后的数值,同时你原有代码中的关键帧存在时间顺序倒退的问题,会导致动画跳变,修正方案如下:
方案1:直接使用计算后的百分比值(原生CSS可用)
提前将分钟数/0.6的结果计算出来,按时间从小到大排列关键帧即可:
div { width: 50px; height: 20px; background-color: blue; position: relative; animation-name: example; animation-duration: 60s; /* 如需真实对应60分钟,将值改为3600s即可 */ animation-iteration-count: infinite; animation-timing-function: linear; /* 匀速动画更符合列车运行效果 */ } @keyframes example { 1.6667% {left:300px; top:0px;} /* neunkirch 对应1分钟 */ 5% {left:200px; top:0px;} /* hallau 对应3分钟 */ 6.6667% {left:200px; top:0px;} /* hallau 对应4分钟 */ 6.6667% {left:100px; top:0px;} /* trasadingen 4分钟出发切换位置 */ 8.3333% {left:100px; top:0px;} /* trasadingen 对应5分钟 */ 13.3333% {left:0px; top:0px;} /* erzingen 对应8分钟 */ 30% {left:0px; top:0px;} /* erzingen 停留到18分钟 */ 31.6667% {left:100px; top:0px;} /* trasadingen 对应19分钟 */ 33.3333% {left:100px; top:0px;} /* trasadingen 对应20分钟 */ 36.6667% {left:200px; top:0px;} /* hallau 对应22分钟 */ 40% {left:200px; top:0px;} /* hallau 对应24分钟 */ 43.3333% {left:300px; top:0px;} /* neunkirch 对应26分钟 */ 50% {left:400px; top:0px;} /* beringen 对应30分钟 */ 53.3333% {left:500px; top:0px;} /* beringerfeld 对应32分钟 */ 58.3333% {left:600px; top:0px;} /* neuhausen bad 对应35分钟 */ 65% {left:700px; top:0px;} /* schaffhausen 对应39分钟 */ 81.6667% {left:700px; top:0px;} /* schaffhausen 停留到49分钟 */ 86.6667% {left:600px; top:0px;} /* neuhausen bad 对应52分钟 */ 90% {left:500px; top:0px;} /* beringerfeld 对应54分钟 */ 91.6667% {left:500px; top:0px;} /* beringerfeld 对应55分钟 */ 93.3333% {left:400px; top:0px;} /* beringen 对应56分钟 */ 95% {left:400px; top:0px;} /* beringen 对应57分钟 */ 100% {left:300px; top:0px;} /* neunkirch 对应60分钟,和起始位置一致循环无卡顿 */ }
配套HTML代码:
<h1>CSS Animation</h1> <div></div>
方案2:使用SCSS预处理器自动计算
如果不想手动计算百分比,可以借助SCSS的函数功能自动转换分钟为百分比:
// 定义分钟转百分比的函数 @function min-to-percent($min) { @return percentage($min / 60); } @keyframes example { #{min-to-percent(1)} {left:300px; top:0px;} /* neunkirch */ #{min-to-percent(3)} {left:200px; top:0px;} /* hallau */ #{min-to-percent(4)} {left:200px; top:0px;} /* hallau */ #{min-to-percent(4)} {left:100px; top:0px;} /* trasadingen */ #{min-to-percent(5)} {left:100px; top:0px;} /* trasadingen */ // 剩余所有帧都可以直接填写分钟数,编译后自动生成正确的百分比值 100% {left:300px; top:0px;} }
内容的提问来源于stack exchange,提问作者Severin Spörri
相关产品推荐
相关产品推荐

