数字跳动动画需用 javascript 配合 requestanimationframe 实现数值渐进更新与缓动效果,再通过 css transform 添加缩放回弹视觉反馈,避免整数截断、格式干扰及性能损耗。

数字跳动动画不是靠 CSS 动画帧(@keyframes)硬“跳”,而是用 JavaScript 控制数值渐进更新 + requestAnimationFrame 或定时器驱动,再配合 CSS 过渡或 transform 实现视觉“弹跳”感。
用 requestAnimationFrame 实现平滑递增
直接用 setTimeout 容易卡顿、不同步屏幕刷新率;requestAnimationFrame 更精准,也更省资源。关键不是“跳”,是“匀速过渡到目标值”,再加一点 easing 模拟弹跳。
- 先读取当前显示的数字(
parseInt(el.textContent)),再确定目标值 - 计算每帧应增加的增量:
(target - current) / totalFrames,但要用缓动函数(如cubic-bezier(0.2, 0.8, 0.4, 1)对应的easeOutCubic)让末尾有回弹感 - 避免整数截断导致最后差 1:用
Math.round()而非Math.floor(),并在最后一帧强制设为target - 示例核心逻辑:
function animateNumber(el, target, duration = 2000) {
const start = parseInt(el.textContent) || 0;
const startTime = performance.now();
const easeOutCubic = t => --t * t * t + 1;
<p>function step(now) {
const elapsed = now - startTime;
const progress = Math.min(elapsed / duration, 1);
const eased = easeOutCubic(progress);
const val = Math.round(start + (target - start) * eased);</p><pre class="brush:php;toolbar:false;">el.textContent = val;
if (progress <p>}
requestAnimationFrame(step);
}</p>CSS 配合实现“跳动”视觉反馈
纯数字变化太干,加一点 scale 变化和 transition 才像“跳”。不能对 textContent 做动画,得用伪元素或包裹层。
- 给数字容器加
position: relative,再用::after显示数字,并设置transform: scale(1)和transition: transform 0.2s - 每次数值更新时,先加 class 触发缩放(比如
animate-bounce),再用setTimeout移除 —— 注意不能靠 CSS 动画循环,否则会干扰 JS 控制节奏 - 更稳妥的做法:用
transform: scale(1.2) translateY(-2px)瞬间触发,再靠 transition 回弹,不依赖 class 切换 - 别对
font-size做动画:重排版开销大,且易抖动
处理多位数字不同步跳动(千位分隔符场景)
如果数字带逗号(如 12,345),直接 parseInt 会截断,且逐位动画容易错乱。必须先剥离格式,动画完再格式化回显。
- 输入前用
String(target).replace(/,/g, '')清洗,输出时用Intl.NumberFormat().format(val)或正则补逗号 - 不要对每个数字字符单独做动画(如拆成
<span>1</span><span>2</span>)—— DOM 节点过多,性能差,且小数点/负号难对齐 - 如果需要“每位独立弹跳”,得用 canvas 或 SVG +
getBoundingClientRect()定位每个 digit,复杂度陡增,一般需求不推荐
真正难的不是写几行 JS,而是控制节奏:太快看不出变化,太慢像卡死;easing 曲线选错,就变成生硬滚动而非跳动;还有服务端返回数字延迟时,要不要加 loading 占位、失败后是否重试——这些边界才决定效果是否“真可用”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











