在JavaScript中,补间动画(Tweening)是一种常见的动画技术,用于在两个值之间平滑过渡。以下是一个简单的补间动画实现,使用了requestAnimationFrame
来实现流畅的动画效果。
线性补间是最简单的补间类型,它在两个值之间以恒定速度移动。
function linearTween(start, end, duration, onUpdate, onComplete) {
let startTime = null;
function step(timestamp) {
if (!startTime) startTime = timestamp;
const progress = Math.min((timestamp - startTime) / duration, 1);
const value = start + (end - start) * progress;
onUpdate(value);
if (progress < 1) {
requestAnimationFrame(step);
} else if (onComplete) {
onComplete();
}
}
requestAnimationFrame(step);
}
// 使用示例
linearTween(0, 100, 1000, (value) => {
console.log(value); // 输出从0到100的值
}, () => {
console.log('Animation complete');
});
缓动补间提供了更复杂的动画效果,例如加速、减速等。可以使用缓动函数来实现这些效果。
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;
}
function easingTween(start, end, duration, onUpdate, onComplete) {
let startTime = null;
function step(timestamp) {
if (!startTime) startTime = timestamp;
const progress = Math.min((timestamp - startTime) / duration, 1);
const value = easeInOutQuad(progress, start, end - start, 1);
onUpdate(value);
if (progress < 1) {
requestAnimationFrame(step);
} else if (onComplete) {
onComplete();
}
}
requestAnimationFrame(step);
}
// 使用示例
easingTween(0, 100, 1000, (value) => {
console.log(value); // 输出从0到100的值,带有缓动效果
}, () => {
console.log('Animation complete');
});
链式补间允许你创建一系列连续的动画。
class ChainedTween {
constructor() {
this.tweens = [];
this.currentTween = null;
}
addTween(start, end, duration, easing = easeInOutQuad) {
this.tweens.push({ start, end, duration, easing });
return this;
}
start(onUpdate, onComplete) {
const nextTween = () => {
if (this.tweens.length > 0) {
const { start, end, duration, easing } = this.tweens.shift();
this.currentTween = { start, end, duration, easing, startTime: null };
requestAnimationFrame(() => this.step(onUpdate, onComplete));
} else if (onComplete) {
onComplete();
}
};
nextTween();
}
step(onUpdate, onComplete) {
const { start, end, duration, easing, startTime } = this.currentTween;
if (!startTime) startTime = performance.now();
const progress = Math.min((performance.now() - startTime) / duration, 1);
const value = easing(progress, start, end - start, 1);
onUpdate(value);
if (progress < 1) {
requestAnimationFrame(() => this.step(onUpdate, onComplete));
} else {
this.currentTween = null;
nextTween();
}
}
}
// 使用示例
const chainedTween = new ChainedTween();
chainedTween.addTween(0, 100, 1000)
.addTween(100, 0, 1000);
chainedTween.start((value) => {
console.log(value); // 输出从0到100再到0的值
}, () => {
console.log('Animation complete');
});
这些示例展示了如何在JavaScript中实现基本的补间动画。你可以根据需要扩展和自定义这些函数,以实现更复杂的动画效果。
领取专属 10元无门槛券
手把手带您无忧上云