前言
在前端开发中,我们常常需要实现各种酷炫的效果来提升用户体验。今天,我要和大家分享一个特别实用的效果——仿拼多多领红包的金额数字滚动效果。
一、效果展示
拼多多的现金大转盘活动中,领取红包后,金额的小数部分会有一个数字滚动的效果。这个效果不仅增加了视觉上的吸引力,还让红包金额的展示更加有趣和生动。
二、滚动原理
数字滚动的原理其实并不复杂。它本质上是一串数字列表在容器内部向上移动。为了实现金额数字的滚动效果,我们需要每次滚动结束之后,重新设置一整串数字。
三、关键布局
了解原理后,我们开始写元素布局。关键布局有两个元素:
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>; };
五、总结
本文介绍了类似拼多多的金额数字滚动效果的实现方法,其中有三个关键点,分别是重置数字数组、计算移动距离和开启关闭动画。通过这些技术点的实现,我们可以在自己的项目中轻松打造出类似的数字滚动效果,为应用增添更多的趣味性和视觉吸引力。