效果演示
视频演示
逻辑思路
例如我们最终要展示的数字为 5878390 ,那么第一个数字就是从1滚动到5停止,第二个数字是从0滚动到5再滚动到8停止,第三个数字是从0滚动到8再滚动到7停止(9之后是0),也就是说从左到右每一位都比前面一位滚动的时间更长,这样就出现了从左到右数字依次出现的效果。
代码实现
生成我们所需的数组
对每一位数字我们都要生成对应的数组。
this.num = '5878390'.split('');
let numArr = [];
this.num.map((item,index) => {
numArr[index] = [];
let i = 0;
// 如果不是第一次循环,要把上一次产生的数组也加进来
if(index != 0){
numArr[index] = numArr[index].concat(numArr[index - 1]);
// 取数组的最后一个赋值给 i
i = numArr[index].pop();
}
while(i != item){
numArr[index].push(i);
i++;
// 这里取余是为了在 i 等于 10 的时候重置为 0
i = i % 10;
}
//由于判断的是 i 不等于 item, 所以最后我们把item加进来
numArr[index].push(item);
})
this.numArr = numArr;
最后生成的数组应该是这样的
html代码
代码中 numArr[indexNum].length - 1 和 index == 0 ? 0 : 33 都是为了在 transform: translateY(-100%); 时正确的展示内容,这里不懂的可以在浏览器中调试css就理解了。
<div class="nums">
<div v-for="(itemNum, indexNum) in num" :key="indexNum">
// 这里通过当前下标设置不同的动画时间,根据当前数字的数组长度来设置高度,
<div
:style="{ height: numArr[indexNum].length - 1 + '00%', animationDuration: indexNum / 10 + 0.5 + 's' }">
<div v-for="(item, index) in numArr[indexNum]" :key="index"
:style="{ height: index == 0 ? 0 : 33 + 'px' }">
{{ item }}
</div>
</div>
</div>
</div>
css代码
.nums {
font-size: 26px;
font-weight: bold;
color: #FFFFFF;
line-height: 33px;
letter-spacing: 1px;
text-shadow: 0px 1px 6px #159AFF;
display: flex;
>div {
height: 33px;
overflow: hidden;
display: flex;
>div {
display: flex;
flex-direction: column-reverse;
animation: numIncrease 1s linear 1.3s;
animation-fill-mode: forwards;
transform: translateY(-100%);
>div {
height: 33px;
text-align: right;
}
}
}
}
@keyframes numIncrease {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}