本文介绍如何使用 Web Animation API 的 playbackRate 属性,在鼠标悬停时将 CSS translate 动画速度精确降低至 50%,避免传统 animation-duration 方案导致的跳帧问题,确保动画状态连续、过渡自然。
本文介绍如何使用 Web Animation API 的 `playbackRate` 属性,在鼠标悬停时将 CSS translate 动画速度精确降低至 50%,避免传统 `animation-duration` 方案导致的跳帧问题,确保动画状态连续、过渡自然。
在实现轮播图或无限滚动横幅(如 Apple 正式的缩略图栏)时,一个常见但棘手的需求是:鼠标悬停时动画减速(如降为原速的 50%),移出后恢复原速,且全程无位置跳变。直接修改 animation-duration 虽然直观,却会强制重置动画时间轴,导致元素瞬间“回弹”或“跳跃”,破坏视觉连贯性。
根本原因在于:CSS 动画的时间重置机制无法维持当前播放进度。解决方案是绕过 CSS 时间声明,转而通过 JavaScript 控制动画的播放速率(playbackRate)——这是 Web Animation API 提供的底层能力,支持对任意 CSS @keyframes 动画进行实时、无损的速度调节。
.carousel {width: 600vw;height: 100%;background: linear-gradient(to right, red, blue, red);background-size: 500vw 100%;animation: move-to-right 2.5s infinite linear;}.container {height: 300px;width: 100vw;overflow: clip;}@keyframes move-to-right {to {translate: -500vw 0;}}
<div class="container"><div class="carousel"></div></div>
const carousel = document.querySelector(".carousel");// 鼠标进入:查找指定名称的动画并设 playbackRate = 0.5(半速)carousel.addEventListener("mouseenter", () => {const anim = carousel.getAnimations().find(a => a.animationName === "move-to-right");if (anim) anim.playbackRate = 0.5;});// 鼠标离开:恢复原速carousel.addEventListener("mouseleave", () => {const anim = carousel.getAnimations().find(a => a.animationName === "move-to-right");if (anim) anim.playbackRate = 1;});
? 关键点说明:
element.getAnimations() 返回当前所有活跃动画的 Animation 对象数组;animationName 属性可精准匹配 @keyframes 名称(注意:需与 CSS 中定义完全一致,含大小写);playbackRate = 0.5 表示以一半速度播放,2.0 则为两倍速,支持小数和负值(反向播放);getAnimations() 和 playbackRate 在现代浏览器(Chrome 84+、Firefox 75+、Safari 16.4+)中已广泛支持;若需兼容旧版 Safari,可添加 webkitTransform 回退逻辑或使用 web-animations-js Polyfill。mouseenter/leave 中重复调用 getAnimations().find(...),建议缓存动画引用或使用 requestAnimationFrame 批量处理多个动画项。move-to-right + fade),务必通过 animationName 精确筛选目标动画,防止误操作。prefers-reduced-motion 媒体查询,对开启“减少运动”设置的用户自动禁用动画或设 playbackRate = 0。通过 Web Animation API 直接操控 playbackRate,不仅解决了减速跳帧这一经典难题,更赋予开发者对动画节奏的像素级控制力——这是纯 CSS 方案难以企及的灵活性与可靠性。