封装动画函数
手动实现一个 countTo 函数
<button class="btn">打折</button> <label for="discount">价格:5000</label>
function animation({ from, to, duration, onProgress }) {
let value = from; // 当前值
const speed = (to - from) / duration; // 变化速度
const startTime = Date.now(); // 动画开始时间
// 让 value 逐步变化
const _step = () => {
const time = Date.now() - startTime; // 动画已执行时间
// 终止条件
if (time >= duration) {
value = to;
onProgress && onProgress(value);
return;
}
// 逐步变化
value = from + speed * time;
onProgress && onProgress(value);
requestAnimationFrame(_step);
};
_step();
}
const label = document.querySelector("label");
const button = document.querySelector(".btn");
button.addEventListener("click", () => {
animation({
from: 5000,
to: 1000,
duration: 1000,
onProgress(value) {
label.textContent = `价格:${value}`;
},
});
});
动画的本质
动画的本质是把一个数字在一段时间内变化到另外一个数字
动画函数
封装动画函数时一般要用到高阶函数和 requestAnimationFrame()
requestAnimationFrame()
是浏览器提供的 API,它会在下一帧渲染之前执行一个回调函数,异步执行
实现动画函数
/**
* @params from 开始值
* @params to 结束值
* @params duration 动画持续时间
* @params onProgress 动画进度回调
*/
function animation({ from, to, duration, onProgress }) {
let value = from; // 当前值
const speed = (to - from) / duration; // 变化速度
const startTime = Date.now(); // 动画开始时间
// 让 value 逐步变化
const _step = () => {
const time = Date.now() - startTime; // 动画已执行时间
// 终止条件
if (time >= duration) {
value = to;
onProgress && onProgress(value);
return;
}
// 逐步变化
value = from + speed * time;
onProgress && onProgress(value);
requestAnimationFrame(_step);
};
_step();
}
button.addEventListener("click", () => {
animation({
from: 5000,
to: 1000,
duration: 1000,
onProgress(value) {
label.textContent = `价格:${value}`;
},
});
});