前言
在前端开发中,我们常常需要实现各种酷炫的效果来提升用户体验。今天,我要和大家分享一个特别实用的效果——仿拼多多领红包的金额数字滚动效果。

一、效果展示
拼多多的现金大转盘活动中,领取红包后,金额的小数部分会有一个数字滚动的效果。这个效果不仅增加了视觉上的吸引力,还让红包金额的展示更加有趣和生动。
二、滚动原理
数字滚动的原理其实并不复杂。它本质上是一串数字列表在容器内部向上移动。为了实现金额数字的滚动效果,我们需要每次滚动结束之后,重新设置一整串数字。
三、关键布局
了解原理后,我们开始写元素布局。关键布局有两个元素:
1. 选择框
选择框用于确认下一个将要变成的数字,我们用它来模拟领取红包之后、金额变化的情况。
2. 数字盒子
数字盒子包括三部分:
• 带 overflow: hidden的外层盒子• 包裹数字并向上滚动的内层盒子 • 一个个数字
const App = function () {
const [options] = useState([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
const [nums, setNums] = useState([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
return (
<main>
<div className="select-box">
<span>改变数字:</span>
<select>
{options.map((v) => (
<option key={v}>{v}</option>
))}
</select>
</div>
<div className="num-box">
<div>
{nums.map((v) => (
<div className="num" key={v}>
{v}
</div>
))}
</div>
</div>
</main>
);
};四、关键逻辑
数字移动的关键逻辑有三个部分:
1. 重置数字数组
如果数组首位是 2,它下面的数字就是 3、4、5、6、7、8、9、0、1。要获取完整的数组,我们可以分为两个步骤:
• 首先,数组首位背后的数字依次加 1,这样数字就变为了 3、4、5、6、7、8、9、10、11; • 然后,所有大于 9 的数字都减去 10,这样数字就变为了 3、4、5、6、7、8、9、0、1。
const getNewNums = (next) => {
const newNums = [];
for (let i = next; i < next + 10; i++) {
const item = i > 9 ? (i - 10) : i;
newNums.push(item);
}
return newNums;
};2. 计算移动距离
用 current 表示当前的数字,next 表示需要变成的数字。计算移动距离时,需要分两种情况考虑:
• next大于current时,只需要移动next - current个数字即可;• next小于current时,需要先移动10 - next个数字,再移动current个数字即可。
const calculateDistance = (current, next) => {
const height = 40;
let diff = next - current;
if (next < current) {
diff = 10 - current + next;
}
return -(diff * height);
};3. 开启关闭动画
数字移动的动画是使用 translateY 和 transition 实现。当数字移动时,我们把 translateY 设置为 calculateDistance 的结果;当移动结束、重置数组时,我们需要把 translateY 设置为 0。
const App = function () {
// ... 省略
const numBoxRef = useRef();
constonChange = (e) => {
// 开启动画
numBoxRef.current.style.transition = "all 1s";
// ... 省略
};
constonTransitionEnd = () => {
// 关闭动画
numBoxRef.current.style.transition = "";
// ... 省略
};
return<main>{/* ... 省略 */}</main>;
};五、总结
本文介绍了类似拼多多的金额数字滚动效果的实现方法,其中有三个关键点,分别是重置数字数组、计算移动距离和开启关闭动画。通过这些技术点的实现,我们可以在自己的项目中轻松打造出类似的数字滚动效果,为应用增添更多的趣味性和视觉吸引力。









