CSS动画—数字轮盘滚动效果的实现

引言

在网页设计中,动画效果往往能给用户带来更加生动和有趣的视觉体验。今天,我们将探讨如何使用CSS动画来实现一个动态数字轮盘滚动效果,这种效果类似于垂直方向的轮播图,可以用于展示计数器、计时器或任何需要动态数字的场景。

原理分析

动态数字轮盘滚动效果的实现基于CSS动画,通过创建一个无限循环的动画来模拟数字的滚动。我们将数字拆分为单个字符,并为每个字符设置不同的延迟时间,以实现数字的连续滚动效果

效果图

实现步骤

1. 父组件

父组件负责接收并传递当前需要显示的数字给子组件AnimateNum。这里我们使用Vue.js框架,通过v-for循环渲染每个场景。

<div class="latestSceneFor" v-for="(item, index) in latestSceneList" :key="index">
  <div class="latestSceneFor-image">
    <img :src="item.url" />
  </div>
  <div class="latestSceneFor-title">
    <div class="name">{{ item.name }}</div>
    <AnimateNum class="value" :curNum="item.value" :size="50"/>  //引用组件
  </div>
</div>


import AnimateNum from '../components/AnimateNum.vue'
components: {
   AnimateNum,
},
data() {
  return {
   latestSceneList: [
      {
        url: require('../assets/images2/basicImg1.png'),
        name: '告警总数',
        value: '121',
      },
      {
        url: require('../assets/images2/basicImg2.png'),
        name: '告警生成事件总数',
        value: '96',
      },
      {
        url: require('../assets/images2/basicImg4.png'),
        name: '告警未处理数',
        value: '30',
      },
      {
        url: require('../assets/images2/basicImg5.png'),
        name: '告警事件超时数',
        value: '12',
      },
    ],
  }
},

<style lang="scss" scoped>
.latestSceneFor {
  width: 50%;
  display: flex;
  align-items: center;
  .latestSceneFor-image {
    display: flex;
    align-items: center;
    width: 115px;
    height: 116px;
    padding-right: 25px;
    img {
      width: 110px;
      height: 100px;
    }
  }
  .latestSceneFor-title {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    flex: 1;
    height: 116px;
    .name {
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 28px;
      color: #ffffff;
    }
    .value {
      font-family: tfont;
      font-size: 46px;
      line-height: 0;
      text-shadow: 0px 1 12 rgba(32, 95, 244, 0.97);
      ::v-deep .scroll-num {
        color: #99eeff;
      }
    }
  }
}
</style>

2. AnimateNum组件

AnimateNum组件接收父组件传递的数字,并将其拆分为单个数字,然后为每个数字创建一个AnimateNumItem实例。每个实例都有其自己的延迟时间,以便它们可以依次停止滚动。

<template>
  <div class="number-box">
    <AnimateNumItem 
		v-for="(item, index) in scrollNumber" 
		:key="'numItem' + index + Date.now()"
		:num="Number(item.num)" 
		:delay="item.delay" 
		:size="item.size"
	/>
  </div>
</template>
<script>
import AnimateNumItem from './AnimateNumItem.vue'
  export default {
    name: 'AnimateNum',
    components: {
      AnimateNumItem
    },
    props: {
      // 自定义尺寸
      size: { type: Number, default: 33 },
      curNum: {
        type: [String, Number],
        default: 0,
      },
    },
    data: () => ({
      showAnimate: true, // 控制无限滚动结束
    }),
    computed: {
      scrollNumber() {
        const numberList = String(this.curNum).split('')
        const list = []
        numberList.map((item, index) => {
          list.push({
            'num': item, // 定位的数字 CSS变量,提供到style使用
            'delay': numberList.length - index, // 每个数字延迟停止
            'size': this.size+'px',
          })
        })
        return list
      },
    },
  }
</script>
<style lang="scss" scoped>
  .number-box {
    display: flex;
    flex-direction: row;
    align-items: center;
  }
</style>

3. AnimateNumItem组件

AnimateNumItem组件是实现单个数字滚动的核心,负责实现单个数字的滚动动画。它接收numdelaysize三个属性,并使用CSS动画来实现数字的滚动效果。动画效果由@keyframes定义,并通过.animate类应用到滚动数字列表上。

<template>
  <div class="scroll-box" :style="scrollStyle" @animationend="showAnimate = false">
    <!-- 使用v-for循环渲染0到9的数字,以供滚动效果使用 -->    
    <ul ref="num" class="scroll-num" :class="{ animate: showAnimate }">
      <li>0</li>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>0</li>
    </ul>
  </div>
</template>
<script>
  export default {
    name: 'AnimateNumItem',
    props: {
      // 定位的数字
      num: {
        type: Number,
        default: 0,
        validator: n => n < 10 && n >= 0 && Number.isInteger(n),
      },
      // 动画延迟时间,控制数字滚动的先后顺序
      delay: { type: Number, default: 1 },
      // 自定义尺寸
      size: { type: String, default: '' },
    },
    data: () => ({
      showAnimate: true, // 控制无限滚动结束
    }),
    computed: {
      scrollStyle() {
        return {
            // 返回一个对象,包含CSS变量,这些变量将在模板中使用
          '--num': this.num,
          '--delay': this.delay,
          '--width': this.size,
        }
      },
    },
  }
</script>
<style lang="scss" scoped>
  /* 定义滚动动画的关键帧 */
  @keyframes move {
    0% {
      transform: translateY(-90%);
      filter: blur(2px);
    }
    100% {
      transform: translateY(1%);
      filter: blur(2px);
    }
  }
  @keyframes num-bounce {
     /* 根据当前数字num的值,计算初始偏移量 */
    0% {
      transform: translateY(calc(var(--num) * -9.09% - 7%));
      filter: none; /* 最后取消模糊效果 */
    }
    25% {
      transform: translateY(calc(var(--num) * -9.09% + 3%));
    }
    50% {
      transform: translateY(calc(var(--num) * -9.09% - 1%));
    }
    70% {
      transform: translateY(calc(var(--num) * -9.09% + 0.6%));
    }
    85% {
      transform: translateY(calc(var(--num) * -9.09% - 0.3%));
    }
    100% {
      transform: translateY(calc(var(--num) * -9.09%));
      filter: none; /* 最后取消模糊效果 */
    }
  }
  .scroll-box {
    width: var(--width, 20px);
    height: calc(var(--width, 20px) * 1.8);
    color: #fff;
    font-size: calc(var(--width, 20px) * 1.1);
    line-height: calc(var(--width, 20px) * 1.8);
    text-align: center;
    overflow: hidden;
    flex-shrink: 0; /* 保证不被压缩 */
  }
  /* 当动画类被激活时应用的样式 */
  .animate {
    animation: move 1s linear infinite, num-bounce 1s calc(var(--delay) * 1s) forwards;
    /* forwards:停在动画的最后一帧 */
  }
  .scroll-num {
    padding: 0;
    margin: 0;
    list-style: none;
    transform: translateY(calc(var(--num) * -9.09%));
  }
</style>

AnimateNumItem组件的样式中,我们定义了两个关键帧动画:movenum-bounce

  • move动画用于创建无限循环的垂直滚动效果。
  • num-bounce动画用于控制数字的滚动和停止,以及设置延迟时间。

结语

通过上述步骤,我们实现了一个数字轮盘滚动的CSS动画效果。这种方法不仅能够提升网页的视觉效果,还能够吸引用户的注意力。希望这篇技术博客能够帮助你在自己的项目中实现类似的动画效果。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值