js 实现数字滚动

数字滚动动画实现
数字滚动动画可以通过多种方式实现,以下是几种常见的实现方法:
使用 CSS 过渡和 JavaScript
function animateValue(id, start, end, duration) {
const obj = document.getElementById(id);
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
obj.innerHTML = Math.floor(progress * (end - start) + start);
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
// 使用示例
animateValue("counter", 0, 100, 2000);
使用 setInterval 实现
function countUp(elementId, target, duration) {
const element = document.getElementById(elementId);
const increment = target / (duration / 16);
let current = 0;
const timer = setInterval(() => {
current += increment;
if (current >= target) {
clearInterval(timer);
current = target;
}
element.textContent = Math.floor(current);
}, 16);
}
// 使用示例
countUp("counter", 100, 2000);
使用 GSAP 动画库
// 引入 GSAP 库后
gsap.to("#counter", {
innerHTML: 100,
duration: 2,
snap: { innerHTML: 1 },
ease: "power1.out"
});
实现带小数点的滚动
function animateDecimal(id, start, end, duration, decimals = 0) {
const element = document.getElementById(id);
const range = end - start;
const increment = end > start ? 1 : -1;
const stepTime = Math.abs(Math.floor(duration / range));
let current = start;
const timer = setInterval(() => {
current += increment;
element.innerHTML = current.toFixed(decimals);
if (current === end) {
clearInterval(timer);
}
}, stepTime);
}
// 使用示例
animateDecimal("counter", 0, 99.99, 2000, 2);
实现带千位分隔符的数字滚动
function animateNumberWithCommas(id, start, end, duration) {
const element = document.getElementById(id);
const range = end - start;
const minTimer = 50;
const stepTime = Math.max(Math.floor(duration / range), minTimer);
let current = start;
const timer = setInterval(() => {
current += 1;
element.innerHTML = current.toLocaleString();
if (current === end) {
clearInterval(timer);
}
}, stepTime);
}
// 使用示例
animateNumberWithCommas("counter", 0, 10000, 2000);
实现缓动效果的滚动
function easeOutQuad(t, b, c, d) {
t /= d;
return -c * t*(t-2) + b;
}
function animateWithEasing(id, start, end, duration) {
const element = document.getElementById(id);
const startTime = performance.now();
function updateNumber(timestamp) {
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easeOutQuad(progress, 0, 1, 1);
const value = Math.floor(start + (end - start) * easedProgress);
element.innerHTML = value;
if (progress < 1) {
requestAnimationFrame(updateNumber);
}
}
requestAnimationFrame(updateNumber);
}
// 使用示例
animateWithEasing("counter", 0, 1000, 2000);
实现注意事项
- 性能考虑:对于大量数字或频繁更新,使用
requestAnimationFrame比setInterval更高效 - 平滑度控制:通过调整持续时间或帧率可以控制动画的平滑程度
- 浏览器兼容性:现代方法如
requestAnimationFrame在大多数现代浏览器中都支持 - 中断处理:应考虑在动画过程中可能的中断情况,如页面切换或元素移除
以上方法可以根据具体需求选择使用,简单的计数器可以使用 setInterval,而更复杂的动画效果建议使用 requestAnimationFrame 或专门的动画库。







