为何CSS与JavaScript中的cubic-bezier动画表现存在差异?
问题根源:缓动函数的作用范围差异
CSS动画与你使用的Web Animations API(Element.animate())对缓动函数的应用逻辑完全不同:
- CSS动画会将指定的缓动函数独立应用到每一对相邻关键帧的区间。比如你的
shake动画中,0%→25%、25%→50%、50%→75%、75%→100%这四个分段,每个都会单独执行一遍cubic-bezier(.36,.07,.19,.97)曲线。 - Web Animations API默认是将缓动函数作用于整个动画的完整时间轴,关键帧只是这条整体曲线上的控制点,而非分段应用缓动。
这种逻辑差异直接导致视觉表现不同:CSS是四段平缓曲线的衔接,而JS动画是整体沿一条曲线运动,因此显得更突兀。
修复方案:给每个关键帧区间单独设置缓动
要让JS动画和CSS效果一致,需要在每个关键帧上指定easing属性,将缓动函数应用到每一段关键帧区间,而非在动画选项中设置全局缓动:
document.querySelector('.js-animation').animate([ { offset: 0.00, transform: 'translateX(0px)', easing: 'cubic-bezier(.36,.07,.19,.97)' }, { offset: 0.25, transform: 'translateX(-20px)', easing: 'cubic-bezier(.36,.07,.19,.97)' }, { offset: 0.50, transform: 'translateX(40px)', easing: 'cubic-bezier(.36,.07,.19,.97)' }, { offset: 0.75, transform: 'translateX(-20px)', easing: 'cubic-bezier(.36,.07,.19,.97)' }, { offset: 1.00, transform: 'translateX(0px)' }, ],{ duration: 1000, iterations: Infinity, });
设置完成后,每个关键帧区间都会单独应用缓动函数,与CSS动画的逻辑完全匹配,视觉效果就会一致。
你也可以用线性缓动linear做验证:此时两种动画的表现会完全相同,因为线性缓动分段应用和整体应用没有区别,这也能反向印证上述逻辑的正确性。
内容的提问来源于stack exchange,提问作者Adam Hunter Peck
相关产品推荐
相关产品推荐

