• css 数字滚动效果


    先看效果图

    在这里插入图片描述

    一、前置条件

    首先了解两个css字符排版的样式

    1. writing-mode

    设置文本行是水平还是垂直布局

    • horizontal-tb:默认值,表示水平排版,从上到下
    • vertical-lr:表示垂直排版,从左到右
    • vertical-rl:表示垂直排版,从右到左
      在这里插入图片描述
      在这里插入图片描述
    2. text-orientation

    设定行中字符的方向,仅影响纵向模式(当 writing-mode 的值不是horizontal-tb)下的文本。此属性在控制使用竖排文字的语言的显示上很有作用,也可以用来构建垂直的表格头

    • mixed:默认值,顺时针旋转水平书写的字符 90°,将垂直书写的文字自然布局
    • upright:将水平书写的字符自然布局(直排),包括垂直书写的文字
    • sideways:所有字符被布局为与水平方式一样,但是整行文本被顺时针旋转 90°

    在这里插入图片描述

    二、滚动原理

    为了效果明显,我们给父元素添加边框作为可视区域,纵向的数字通过transform在Y轴位移达到滚动效果

        <template>
        	<div class="number">
          		<span>0123456879span>
    	    div>
        template>
        <style scoped>
    		.number {
    		  width: 20px;
    		  height: 20px;
    		  border: 1px solid #333;
    		}
    		.number span {
    		  writing-mode: vertical-rl;
    		  text-orientation: upright;
    		  transform: translateY(0%);
      		}
    	style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    如下图所示

    在这里插入图片描述
    我们接着把边框去掉,换成overflow: hidden

    在这里插入图片描述


    假如现在有一个6位数字123456,我们想要它从000000滚动到目标数字123456

    代码部分:

    <template>
      <div style="margin-left: 300px;margin-top: 300px;display: flex;align-items: center;">
        <div v-for="(item, index) in numberList" :key="index" style="display: flex;">
          <div class="number">
            <span ref="numberItem" :data-number="item" :data-index="index">0123456879span>
          div>
        div>
        <a-button style="margin-left: 30px;" @click="setNumberTransform">滚动a-button>
      div>
    template>
    
    <script>
    export default {
      computed: {
        numberList() {
          return String(this.value).split("");
        }
      },
      data() {
        return {
          value: 123456
        };
      },
      methods: {
        // 设置每一位数字的偏移
        setNumberTransform() {
          let numberItems = this.$refs.numberItem;
          let obj = {}
          Array.from(numberItems).forEach(c => {
            let key = c.dataset.index
            let value = c.dataset.number
            let init = 0
            obj[key] = setInterval(() => {
              if (init < value * 10) {
                init++
                c.style.transform = `translateY(-${init}%)`;
              } else {
                clearInterval(obj[key])
                obj[key] = null
              }
            }, 10);  // 控制滚动速率
          });
        }
      },
    };
    script>
    
    <style scoped lang="less">
    .number {
      width: 20px;
      height: 20px;
      border: 1px solid #ccc;
      > span {
        writing-mode: vertical-rl;
        text-orientation: upright;
        transform: translateY(0%);
      }
    }
    style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    效果如下:
    在这里插入图片描述
    我们接着把边框去掉,换成overflow: hidden,效果如下:

    在这里插入图片描述

    三、封装数字滚动组件

    创建scroll-number.vue数字滚动组件

    <template>
      <div style="display: flex;">
        <div v-for="(item, index) in numberList" :key="index" style="display: flex;">
          <span v-if="isNaN(item)">{{item}}span>
          <div class="number" v-else>
            <span
              class="number-item"
              ref="numberItem"
              :data-number="item"
              :data-index="index"
            >0123456879span>
          div>
        div>
      div>
    template>
    
    <script>
    export default {
      props: {
        value: {
          type: [String, Number],
          default: 0
        }
      },
      watch: {
        value(newVal) {
          if (newVal) {
            this.$nextTick(() => {
              this.setNumberTransform();
            });
          }
        }
      },
      computed: {
        numberList() {
          return String(this.value).split("");
        }
      },
      data() {
        return {};
      },
      methods: {
        // 设置每一位数字的偏移
        setNumberTransform() {
          let numberItems = this.$refs.numberItem;
          let obj = {};
          Array.from(numberItems).forEach(c => {
            let key = c.dataset.index;
            let value = c.dataset.number;
            let init = 0;
            obj[key] = setInterval(() => {
              if (init < value * 10) {
                init += 1;
                c.style.transform = `translateY(-${init}%)`;
              } else {
                clearInterval(obj[key]);
                obj[key] = null;
              }
            }, 10);
          });
        }
      },
      mounted() {
        this.setNumberTransform();
      }
    };
    script>
    
    <style scoped lang="less">
    .number {
      width: 20px;
      height: 20px;
      overflow: hidden;
      > span {
        writing-mode: vertical-rl;
        text-orientation: upright;
        transform: translateY(0%);
      }
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    使用改组件

     <scroll-number :value="'412,789,123,41.00'">scroll-number>
    
    • 1

    效果如下图

    在这里插入图片描述

  • 相关阅读:
    【设计模式】工厂模式(c++实现)
    MyBatis 源码分析之 Mapper 接口代理对象生成及方法执行
    白盒测试(结构测试)
    条件随机场(CRF)笔记
    重磅,瑞士药监局 发布 EU GMP附录1《无菌药品生产》官方解读!
    rtthread下基于spi device架构MCP25625驱动
    pip快速安装torch、opencv、scipy库
    另眼旁观 Linkerd 2.12 的发布:服务网格标准的曙光?
    JAVA:实现文件中出现频率最高的K个单词以及出现的次数算法(附完整源码)
    Dubbo 提供者与消费者的实现
  • 原文地址:https://blog.csdn.net/guizi0809/article/details/125857260