可视化大屏上的数字翻滚动画实现原理

2,952 阅读3分钟

前言

大家好,我是飞叶,一个前端UP主,今天给大家带来一个数字翻滚动画的实现。

数字翻滚动画实现

大家在可视化大屏上或者年会抽奖上,都见到过这种数字翻滚动画。

可以先给大家看看demo效果。

地址 左侧菜单,第二个AniNumber就是数字翻滚组件。

那么如何实现它呢?我搜了一下,发现大家的实现方式还挺多的,但是有一个明显的技术卡点是如何 让动画停在指定的数字上。

有的实现方式让数字先疯狂转起来,然后动画突然停住后切换到指定数字显示,利用视觉反应没那么快的原理,让大家觉得 动画是平滑的,但是这种方案明显不行,一个是如果要求不让数字转那么快就不行了,第二个是设计师们都是火眼金睛, 不要假想他们发现不了这一点。

还有的实现方式是在动画停住后,做一个回弹效果,总之也是为了避开让动画停在指定数字上的技术卡点。

关于这两种实现方案,大家真正在做此类需求的时候,百度搜一下,就能找到。

我认为这样的方式不够完美,所以思考了一下,自己实现了一把。 我这里画了一张图来解释原理。

实现原理

假如我们要从数字72翻滚到数字324。

第一件事是检查起始数字和目标数字的位数是否相同。如果不同,则对初始数位补0; (我这里的实现是假设数字一直是向上增的,所以肯定是起始数字位数不够)。

第二,我们要把每个数位的动画分开。其实他们是独立的1个动画,重复了3次而已。

接下来是最重要的,如何进行动画实现呢?

每个数位下其实都是一个数组,数组里已经计算好了所有要进行动画的数字。

比如拿中间的十位举例,起始数字是7,目标数字是2。 那这一数位的数组就是 【7,8,9,0 ... 9,0 ... 9,0,1,2】。 当然至于中间要循环几遍0-9,你自己决定。

当你把数组准备好了,真正执行动画的部分就非常简单了。如下:

@keyframes up{
        0%{
          transform: translateY(0);
        }
        100%{
          transform: translateY(var(--translate));
        }
      }

然后应用动画即可:

.ani{
      animation-name: up;
      animation-timing-function: ease-in-out;
      animation-iteration-count: 1;
      animation-duration: var(--duration);
      animation-fill-mode: both;
      animation-delay: var(--delay);
    }

如何用这个组件

我知道大家不一定想自己实现一遍,所以我将其封装了组件。 大家可以直接使用。

安装

npm i flyleaf

使用

import { AniNumber } from 'flyleaf';
const div = new AniNumber({
  target: document.getElementById('app'),
  props: {
    startNum: 182, // 开始数字
    targetNum: 200, // 要滚动到的目标数字
    duration: 3, // 单位是秒
    direction: 'up', // up、down
    isStart: true, // 是否立即开始动画
    circleNum: 2, // 0-9要循环几圈,也是一种控制速度/动画时间的方式
  }
})

非常的简单!

最后

最后,我也录了一个视频来讲这个动画,放在B站了,可以去看。 也欢迎关注我。