js如何实现数字滚动效果 数字动态增长动画实现

js如何实现数字滚动效果 数字动态增长动画实现
最新回答
恭候春夏的轮替

2022-01-11 21:07:24

实现数字滚动效果(数字动态增长动画)的核心是利用JavaScript在指定时间内平滑更新数字值,以下是三种常见方法及详细实现方案:

一、推荐方案:requestAnimationFrame + 数神历学计算(性能最佳)

通过requestAnimationFrame实现流畅动画,结合数学计算控制数字变化,支册伏持自定义缓动函数和格式化输出。

function easeOutQuad(t) { return t * (2 - t); } // 缓动函数:减速效果function animateNumber(elementId, start, end, duration) { const element = document.getElementById(elementId); const startTime = performance.now(); function updateNumber(currentTime) { const elapsedTime = currentTime - startTime; const rawProgress = elapsedTime / duration; const progress = easeOutQuad(Math.min(rawProgress, 1)); // 应用缓动函数 // 处理整数或小数显示 const value = start + (end - start) * progress; element.textContent = value % 1 !== 0 ? value.toFixed(2) : Math.floor(value); if (progress < 1) { requestAnimationFrame(updateNumber); } } requestAnimationFrame(updateNumber);}// 使用示例:2秒内从0滚动到12345.56animateNumber('myNumber', 0, 12345.56, 2000);

优势

  • 性能卓越:浏览器优化渲染时机,避免卡顿
  • 高度可控:支持自定义动画时长、起始/结束值、缓动效果
  • 灵活扩展:可轻松添加千分位分隔符、货币符号等格式化功能

优化技巧

  1. 减少DOM操作:批量更新数字而非频繁操作
  2. 硬件加速:为元素添加will-change: transform属性
  3. 节流控制:高频更新时使用节流函数限制帧率
二、备选方案:CSS Transitions/Animations(简单场景)

通过CSS的transform属性模拟数字滚动,适合静态数字列表的简单动画。

<div class="number-container"> <div class="number-track"> <span>0</span><span>1</span><span>2</span>...<span>12345</span> </div></div><style>.number-container { height: 1em; overflow: hidden;}.number-track { display: flex; flex-direction: column; transition: transform 2s ease-out;}/* 通过JS动态修改transform: translateY(-X%)实现滚动 */</style>

局限性

  • 需预先生成所有数字节点
  • 难以实现动态数值的精确控制
  • 缓动效果有限
三、快州瞎携速方案:第三方库(CountUp.js)

适合需要快速实现且接受外部依赖的项目。

<script src="
https://cdn.jsdelivr.net/npm/countup.js@2.0.7/dist/countUp.min.js"></script><div
id="myNumber">0</div><script> const countUp = new CountUp('myNumber', 12345.56, { duration: 2, easingFn: (t) => t * (2 - t) // 自定义缓动函数 }); countUp.start();</script>

注意事项

  • 增加项目体积(约10KB gzipped)
  • 可能存在兼容性问题
  • 自定义能力受限
关键问题解决方案1. 数字精度处理

问题:toFixed()可能导致1.005 → 1.00的精度丢失解决方案

function preciseRound(number, precision) { const factor = 10 precision; return Math.round(number * factor) / factor;}// 使用示例preciseRound(1.005, 2); // 返回1.012. 动画自然度提升

核心技巧:应用缓动函数(Easing Functions)

// 更多缓动函数示例const easingFunctions = { easeInQuad: t => t * t, easeOutElastic: t => Math.pow(2, -10 * t) * Math.sin((t - 0.3 / 4) * (2 * Math.PI) / 0.3) + 1};// 在animateNumber函数中替换progress计算方式即可3. 性能优化策略
  • 批量更新:合并多个数字动画的DOM操作
  • 分层渲染:将动画元素提升到独立图层(transform: translateZ(0))
  • 时间校准:使用performance.now()替代Date.now()获取精确时间戳
完整实现示例(含格式化)function formatNumber(value) { // 添加千分位分隔符 return value.toString().replace(/B(?=(d{3})+(?!d))/g, ",");}function animatedCounter(elementId, options) { const { start = 0, end, duration = 2000, decimalPlaces = 0 } = options; const element = document.getElementById(elementId); const startTime = performance.now(); function update(currentTime) { const progress = Math.min((currentTime - startTime) / duration, 1); const easedProgress = easeOutQuad(progress); const rawValue = start + (end - start) * easedProgress; // 处理小数精度 const displayValue = decimalPlaces > 0 ? preciseRound(rawValue, decimalPlaces) : Math.floor(rawValue); element.textContent = formatNumber(displayValue); if (progress < 1) { requestAnimationFrame(update); } } requestAnimationFrame(update);}// 使用示例animatedCounter('counter', { end: 1234567.89, duration: 3000, decimalPlaces: 2});

选择方案时建议:

  • 优先推荐:requestAnimationFrame方案(90%场景适用)
  • 简单需求:CSS方案(仅固定数字列表)
  • 快速开发:CountUp.js(需引入外部库)

通过合理应用缓动函数、格式化输出和性能优化技术,可创建出既流畅又符合业务需求的数字滚动动画效果。