缓动动画是一种常见的动画效果,它在动画运行初期速度较快,在结束时速度逐渐减慢,运动距离也逐渐减小,这种动画效果更符合人眼的视觉特性,所以受到广泛的应用。
在 JavaScript 中,我们可以通过封装函数来实现缓动动画,下面我们就来详细讲解一下。
首先,我们需要知道缓动动画的原理,即在动画过程中,物体运动的距离和时间之间并不具有线性关系,而是一个缓动函数的结果,比如说我们常用的 ease-in-out 函数。因此,我们需要封装一个可以接受运行时间、起始位置、结束位置、缓动函数等参数的缓动动画函数。
具体实现思路如下:
下面给出两个示例,一个是缓动函数的实现,一个是缓动动画的封装。
/**
* 缓动函数
* @param {number} t 当前时间
* @param {number} b 初始值
* @param {number} c 变化量
* @param {number} d 持续时间
* @return {number} 当前值
*/
function easeInOutQuad(t, b, c, d) {
t /= d/2;
if (t < 1) return c/2*t*t + b;
t--;
return -c/2 * (t*(t-2) - 1) + b;
}
上面的代码中,我们实现了一个缓动函数 easeInOutQuad,它接受当前时间 t,初始值 b,变化量 c 和持续时间 d 作为参数,并返回当前值。
/**
* 缓动动画函数
* @param {HTMLElement} ele 动画元素
* @param {object} target 动画目标值
* @param {number} duration 动画持续时间
* @param {function} easing 缓动函数
*/
function animate(ele, target, duration, easing) {
// 记录动画起始时间
const startTime = new Date().getTime();
// 记录动画初始值
const startStyle = {};
for (const key in target) {
startStyle[key] = parseInt(getComputedStyle(ele)[key]);
}
const tick = () => {
// 计算时间差和当前值
const elapsed = new Date().getTime() - startTime;
const ratio = elapsed / duration;
const progress = easing(ratio, 0, 1, 1);
for (const key in target) {
const value = startStyle[key] + (target[key] - startStyle[key]) * progress;
ele.style[key] = value + 'px';
}
if (elapsed < duration) {
// 动画未结束,继续运动
requestAnimationFrame(tick);
} else {
// 动画结束,清除定时器
for (const key in target) {
ele.style[key] = target[key] + 'px';
}
}
};
tick();
}
上面的代码中,我们实现了一个 animate 函数,它接受动画元素 ele、动画目标值 target、动画持续时间 duration 和缓动函数 easing 作为参数,并实现了缓动动画的封装。
其中,我们首先记录动画起始时间和元素的初始值,在每一帧计算当前值,并根据缓动函数获取当前进度,最后根据计算得到的目标值判断动画是否结束,如果未结束,则继续使用 requestAnimationFrame 函数继续执行缓动函数。
缓动动画的实现需要封装缓动函数和缓动动画函数。实现缓动函数需要了解缓动动画的计算原理,而实现缓动动画函数则需要对缓动函数进行合理的调用和适当的封装,以实现复杂的动画效果。