数字滚动计数
数字从 0 滚到目标值,先快后慢稳稳停住
全平台通用动效与背景内容区效果
实时预览(拖动参数,立刻看变化)
代码
<div id="counter">0</div>
<script>
function countTo(el, target, duration = 1600) {
const t0 = performance.now();
const ease = t => 1 - Math.pow(1 - t, 3); // easeOutCubic
(function step(t) {
const k = Math.min(1, (t - t0) / duration);
el.textContent = Math.round(target * ease(k)).toLocaleString('en-US');
if (k < 1) requestAnimationFrame(step);
})(t0);
}
countTo(document.getElementById('counter'), 12800);
</script> <!-- Tailwind 只管样式,计数逻辑仍用 html-css 档的脚本 -->
<div id="counter" class="text-6xl font-extrabold tabular-nums tracking-tight">0</div> export function Counter({ target = 12800, duration = 1600 }) {
const [v, setV] = React.useState(0);
React.useEffect(() => {
const t0 = performance.now(); let raf;
const step = (t) => { const k = Math.min(1, (t - t0) / duration);
setV(Math.round(target * (1 - Math.pow(1 - k, 3))));
if (k < 1) raf = requestAnimationFrame(step); };
raf = requestAnimationFrame(step);
return () => cancelAnimationFrame(raf);
}, [target, duration]);
return <span className="tabular-nums">{v.toLocaleString('en-US')}</span>;
} 代码片段以 MIT 释出,可自由复制改用。
这个效果是怎么实现的
它是怎么工作的(中文)
用 requestAnimationFrame 按进度取缓动值,把「已过时间 ÷ 总时长」喂给 easeOutCubic 再乘目标值。数字字体记得开 tabular-nums(等宽数字),否则滚动时整行会左右抖。计数只用在「数字本身是主角」的统计场景,别给每个小数字都加。
How it works (English)
Drive it with requestAnimationFrame: feed elapsed/duration through easeOutCubic and multiply by the target. Turn on tabular-nums (monospaced figures) or the line will jitter as digits change width. Reserve counters for stats where the number is the hero — not every small figure deserves one.
参考与来源 Sources
本条为「批次 1(重建)」成果(2026-11-10 用户决定:原 妞妞老师 素材不导出,改由公开材料重建):效果概念参考开源效果生态——Magic UI(MIT)、Uiverse(MIT)、Animista、Paper Shaders(Apache-2.0)、tsParticles(MIT)、CSS Loaders(MIT)等(见 /resources 对应条目,许可以各项目为准);本站的实现代码、参数体系与全部文案均为 Aglaia 原创,未复制上述项目的代码或文案,也与 妞妞老师 原始素材无关。