js实现缓动
缓动动画的实现原理
缓动动画(Easing Animation)通过改变动画的速率变化,让运动效果更加自然。常见缓动类型包括线性、二次、三次、弹性等,每种类型都能产生不同的视觉效果。
线性缓动实现
线性缓动是最简单的形式,动画速度恒定:
function linearEase(t, b, c, d) {
return c * t / d + b;
}
参数说明:
t:当前时间b:初始值c:变化量(目标值-初始值)d:持续时间
二次缓动实现
二次缓动(Quadratic Easing)分为加速和减速两种:
// 加速缓动
function easeInQuad(t, b, c, d) {
return c * (t /= d) * t + b;
}
// 减速缓动
function easeOutQuad(t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
}
// 先加速后减速
function easeInOutQuad(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}
三次缓动实现
三次缓动(Cubic Easing)效果比二次更明显:
function easeInCubic(t, b, c, d) {
return c * (t /= d) * t * t + b;
}
function easeOutCubic(t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
}
弹性缓动实现
弹性缓动(Elastic Easing)模拟弹簧效果:
function easeOutElastic(t, b, c, d) {
let s = 1.70158;
let p = 0;
let a = c;
if (t == 0) return b;
if ((t /= d) == 1) return b + c;
if (!p) p = d * 0.3;
if (a < Math.abs(c)) {
a = c;
s = p / 4;
} else {
s = p / (2 * Math.PI) * Math.asin(c / a);
}
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
}
动画循环实现
使用requestAnimationFrame实现动画循环:
function animate({ duration, easing, draw }) {
let start = performance.now();
requestAnimationFrame(function animateFrame(time) {
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
let progress = easing(timeFraction);
draw(progress);
if (timeFraction < 1) {
requestAnimationFrame(animateFrame);
}
});
}
// 使用示例
animate({
duration: 1000,
easing: easeOutQuad,
draw: (progress) => {
element.style.left = progress * 500 + 'px';
}
});
缓动函数可视化工具
可以通过可视化工具直观比较不同缓动效果:
性能优化建议
避免在动画中频繁触发重排(reflow):
- 使用transform替代top/left动画
- 将will-change属性应用于动画元素
- 减少动画元素的数量
- 对复杂动画考虑使用CSS硬件加速
现代API替代方案
CSS动画原生支持缓动:
.element {
transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
Web Animations API也提供缓动控制:
element.animate([
{ transform: 'translateX(0)' },
{ transform: 'translateX(300px)' }
], {
duration: 1000,
easing: 'cubic-bezier(0.42, 0, 0.58, 1)'
});






