如何实现基于实际秒数计算的时钟秒针平滑旋转效果
解决方案
完全可以实现,这里提供两种常用实现方案,都能满足「对齐实际时间+平滑旋转」的需求:
方案1:JS计算带毫秒的实时角度,高刷新率更新
核心思路是计算角度时不再只取整秒,而是把当前秒的毫秒进度也算进去,同时用requestAnimationFrame代替1秒一次的定时器,高频更新角度自然实现平滑效果:
JS代码
function clockRunner() { const date = new Date(); // 计算包含毫秒的总秒数,1秒=1000毫秒,除以1000得到带小数的秒数 const currentSecond = date.getSeconds() + date.getMilliseconds() / 1000; const secondRotation = 6 * currentSecond + "deg"; const secondNeedle = document.getElementById("secondNeedle"); secondNeedle.style.transform = "rotate(" + secondRotation + ")"; secondNeedle.style.transformOrigin = "center 91%"; // 递归调用实现高频刷新 requestAnimationFrame(clockRunner); } // 页面加载就启动 requestAnimationFrame(clockRunner);
CSS代码(原有代码无需修改)
#secondNeedle { position: absolute; height: 46%; width: 1%; top: 8%; left: 49.5%; background-color: rgba(0, 0, 0); }
HTML代码
<div id="secondNeedle"></div>
方案2:CSS动画加初始时间偏移,性能更优
核心思路是复用你写的CSS无限动画逻辑,只需要在页面加载时计算当前秒数对应的偏移量,给动画设置负的animation-delay让动画直接跳转到对应时间点,全程由CSS驱动动画,性能比JS高频更新更好:
CSS代码
#secondNeedle { position: absolute; height: 46%; width: 1%; top: 8%; left: 49.5%; background-color: rgba(0, 0, 0); transform-origin: center 91%; } @keyframes example { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }
JS代码(仅需要页面加载时执行一次设置偏移)
window.addEventListener('load', () => { const date = new Date(); const currentSecond = date.getSeconds() + date.getMilliseconds() / 1000; const secondNeedle = document.getElementById("secondNeedle"); // 负的延迟表示动画直接跳到已经运行了currentSecond秒的位置 secondNeedle.style.animation = `example 60s linear -${currentSecond}s infinite`; })
HTML代码
<div id="secondNeedle"></div>
两种方案都能完全对齐真实时间,无跳针问题,追求开发简单选方案1,追求性能选方案2即可。
内容的提问来源于stack exchange,提问作者Yupma
相关产品推荐
相关产品推荐

