大屏数字滚动翻转效果来源于最近工作中element后台管理页面一张大屏的UI图,该UI图上有一个模块需要有数字往上翻动的效果,以下是最终实现的效果:

整体思路:

在实现此效果之前,我们先来捋一下思路,用思维导图来设计一下我们的实现步骤,如下:

你可以审查元素,下载数字背景图片,复制图片地址,或者使用其他背景图片、背景颜色

有了以上的设计流程,我们先来简单实现一下:

  1. // CSS代码
  2. <style>
  3. .box-item {
  4. position: relative;
  5. display: inline-block;
  6. width: 54px;
  7. height: 82px;
  8. /* 背景图片 */
  9. background: url(./number-bg.png) no-repeat center center;
  10. background-size: 100% 100%;
  11. font-size: 62px;
  12. line-height: 82px;
  13. text-align: center;
  14. }
  15. </style>
  16.  
  17. // htm代码
  18. <div class="box">
  19. <p class="box-item">
  20. <span>1</span>
  21. </p>
  22. </div>

  

实现以上代码后,它的效果将是下面这样的:

思考:背景框中有了数字以后,我们现在来思考一下,背景框中的文字,一定是 0-9 之前的数字,要在不打乱以上 html 结构的前提下,如何让数字滚动起来呢?这个时候我们的魔爪就伸向了一个 CSS 属性: writing-mode ,下面是它属性的介绍:

  • horizontal-tb:默认值,表示水平排版,从上到下。
  • vertical-lr:表示垂直排版,从左到右。
  • vertical-rl:表示垂直排版,从右到左。

它的实时效果是像下面这样:

根据以上的灵感,我们可以实现下面这样的效果:

代码如下:

  1. // html部分
  2. <p class="box-item">
  3. <span>0123456789</span>
  4. </p>
  5.  
  6. // style部分
  7. .box-item {
  8. display: inline-block;
  9. width: 54px;
  10. height: 82px;
  11. background: url(./number-bg.png) no-repeat center center;
  12. background-size: 100% 100%;
  13. font-size: 62px;
  14. line-height: 82px;
  15. text-align: center;
  16. position: relative;
  17. writing-mode: vertical-lr;
  18. text-orientation: upright;
  19. /* overflow: hidden; */
  20. }
  21. .box-item span {
  22. position: absolute;
  23. top: 10px;
  24. left: 50%;
  25. transform: translateX(-50%);
  26. letter-spacing: 10px;
  27. }

  

计算滚动

如果我们想让数字滚动到 5 ,那么滚动的具体到底是多少?

答案是:向下滚动 -50%

那么其他的数字呢?

得益于我们特殊的实现方法,每一位数字的滚动距离有一个通用的公式:

  1. transform: `translate(-50%,-${number * 10}%)

有了以上公式,我们让数字滚动到 5 ,它的效果如下:

代码加上  `transform: `translate(-50%,-${number * 10}%)`,示例如下

  1. .box-item span {
  2. position: absolute;
  3. top: 10px;
  4. left: 50%;
  5. transform: translate(-50%,-50%);
  6. letter-spacing: 10px;
  7. }

  

滚动动画的实现

在知道了每一个数字具体的滚动距离后,我们来设计一下,让数字能够随机滚动起来:

一下是让数字随机滚动的JS

  1. setInterval(() => {
  2. let number = document.getElementById('Number')
  3. let random = getRandomNumber(0,10)
  4. number.style.transform = `translate(-50%, -${random * 10}%)`
  5. }, 2000)
  6. function getRandomNumber (min, max) {
  7. return Math.floor(Math.random() * (max - min + 1) + min)
  8. }

  

至此,我们数字滚动效果已经初步实现了,在下一节中我们将会逐步完善此效果,以满足业务需求。

完善

在上一节中,我们初步完成了滚动的效果,这一节我们将根据最开始的思维导图来设计一个通用的 Vue 业务组件

因为我们的业务需要,我们最大的位数是 8 位数字,所以对不足八位进行补位:

假如传递的位数不足 8 位,我们需要对它进行补 0 的操作,补 0 完成以后,我们也需要把它转换成金额的格式

  1. toOrderNum(num) {
  2. num = num.toString()
  3. // 把订单数变成字符串
  4. if (num.length < 8) {
  5. num = '0' + num // 如未满八位数,添加"0"补位
  6. this.toOrderNum(num) // 递归添加"0"补位
  7. } else if (num.length === 8) {
  8. // 订单数中加入逗号
  9. num = num.slice(0, 2) + ',' + num.slice(2, 5) + ',' + num.slice(5, 8)
  10. this.orderNum = num.split('') // 将其便变成数据,渲染至滚动数组
  11. } else {
  12. // 订单总量数字超过八位显示异常
  13. this.$message.warning('订单总量数字过大,显示异常,请联系客服')
  14. }
  15. },

  

渲染

我们根据上面补位字符串,分隔成字符数组,在页面中进行渲染:

computeNumber:为字符数组,例如:['0','0',',','0','0','0',',','9','1','7']

  1. // html代码
  2. <ul>
  3. <li
  4. :class="{'number-item': !isNaN(item) }"
  5. v-for="(item,index) in computeNumber"
  6. :key="index"
  7. >
  8. <span v-if="!isNaN(item)">
  9. <i ref="numberItem">0123456789</i>
  10. </span>
  11. <span v-else>{{item}}</span>
  12. </li>
  13. </ul>
  14.  
  15. // CSS代码
  16. .number-item {
  17. width: 50px;
  18. background: url(./number-bg.png) no-repeat center center;
  19. background-size:100% 100%;
  20. & > span {
  21. position: relative;
  22. display: inline-block;
  23. margin-right: 10px;
  24. width: 100%;
  25. height: 100%;
  26. writing-mode: vertical-rl;
  27. text-orientation: upright;
  28. overflow: hidden;
  29. & > i {
  30. position: absolute;
  31. top: 0;
  32. left: 50%;
  33. transform: translate(-50%,0);
  34. transition: transform 0.5s ease-in-out;
  35. letter-spacing: 10px;
  36. }
  37. }
  38. }

  

页面渲染效果:

数字随机增长,模拟轮询效果

页面渲染完毕后,我们来让数字滚动起来,设计如下两个方法,其中 increaseNumber 需要在 Vue 生命周期 mounted 函数中调用

  1. // 定时增长数字
  2. increaseNumber () {
  3. let self = this
  4. this.timer = setInterval(() => {
  5. self.newNumber = self.newNumber + getRandomNumber(1, 100)
  6. self.setNumberTransform()
  7. }, 3000)
  8. },
  9. // 设置每一位数字的偏移
  10. setNumberTransform () {
  11. let numberItems = this.$refs.numberItem
  12. let numberArr = this.computeNumber.filter(item => !isNaN(item))
  13. for (let index = 0; index < numberItems.length; index++) {
  14. let elem = numberItems[index]
  15. elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`
  16. }
  17. }

  

最终实现效果:

完整代码如下:

  1. <template>
  2. <div class="chartNum">
  3. <h3 class="orderTitle">订单总量</h3>
  4. <div class="box-item">
  5. <li :class="{'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
  6. v-for="(item,index) in orderNum"
  7. :key="index">
  8. <span v-if="!isNaN(item)">
  9. <i ref="numberItem">0123456789</i>
  10. </span>
  11. <span class="comma" v-else>{{item}}</span>
  12. </li>
  13. </div>
  14. </div>
  15. </template>
  16. <script>
  17. export default {
  18. data() {
  19. return {
  20. orderNum: ['0', '0', ',', '0', '0', '0', ',', '0', '0', '0'], // 默认订单总数
  21. }
  22. },
  23. mounted() {
  24.  
  25.       this.$nextTick(() => {
  26.        this.toOrderNum(1213123) // 这里输入数字即可调用
  27.       this.setNumberTransform()
  28.       })
  29. },
  30. methods: {
  31. // 设置文字滚动
  32. setNumberTransform () {
  33. const numberItems = this.$refs.numberItem // 拿到数字的ref,计算元素数量
  34. const numberArr = this.orderNum.filter(item => !isNaN(item))
  35. // 结合CSS 对数字字符进行滚动,显示订单数量
  36. for (let index = 0; index < numberItems.length; index++) {
  37. const elem = numberItems[index]
  38. elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`
  39. }
  40. },
  41. // 处理总订单数字
  42. toOrderNum(num) {
  43. num = num.toString()
  44. // 把订单数变成字符串
  45. if (num.length < 8) {
  46. num = '0' + num // 如未满八位数,添加"0"补位
  47. this.toOrderNum(num) // 递归添加"0"补位
  48. } else if (num.length === 8) {
  49. // 订单数中加入逗号
  50. num = num.slice(0, 2) + ',' + num.slice(2, 5) + ',' + num.slice(5, 8)
  51. this.orderNum = num.split('') // 将其便变成数据,渲染至滚动数组
  52. } else {
  53. // 订单总量数字超过八位显示异常
  54. this.$message.warning('订单总量数字过大,显示异常,请联系客服')
  55. }
  56. },
  57. }
  58. }
  59. </script>
  60. <style scoped lang='scss'>
  61. /*订单总量滚动数字设置*/
  62. .box-item {
  63. position: relative;
  64. height: 100px;
  65. font-size: 54px;
  66. line-height: 41px;
  67. text-align: center;
  68. list-style: none;
  69. color: #2D7CFF;
  70. writing-mode: vertical-lr;
  71. text-orientation: upright;
  72. /*文字禁止编辑*/
  73. -moz-user-select: none; /*火狐*/
  74. -webkit-user-select: none; /*webkit浏览器*/
  75. -ms-user-select: none; /*IE10*/
  76. -khtml-user-select: none; /*早期浏览器*/
  77. user-select: none;
  78. /* overflow: hidden; */
  79. }
  80. /* 默认逗号设置 */
  81. .mark-item {
  82. width: 10px;
  83. height: 100px;
  84. margin-right: 5px;
  85. line-height: 10px;
  86. font-size: 48px;
  87. position: relative;
  88. & > span {
  89. position: absolute;
  90. width: 100%;
  91. bottom: 0;
  92. writing-mode: vertical-rl;
  93. text-orientation: upright;
  94. }
  95. }
  96. /*滚动数字设置*/
  97. .number-item {
  98. width: 41px;
  99. height: 75px;
  100. background: #ccc;
  101. list-style: none;
  102. margin-right: 5px;
  103. background:rgba(250,250,250,1);
  104. border-radius:4px;
  105. border:1px solid rgba(221,221,221,1);
  106. & > span {
  107. position: relative;
  108. display: inline-block;
  109. margin-right: 10px;
  110. width: 100%;
  111. height: 100%;
  112. writing-mode: vertical-rl;
  113. text-orientation: upright;
  114. overflow: hidden;
  115. & > i {
  116. font-style: normal;
  117. position: absolute;
  118. top: 11px;
  119. left: 50%;
  120. transform: translate(-50%,0);
  121. transition: transform 1s ease-in-out;
  122. letter-spacing: 10px;
  123. }
  124. }
  125. }
  126. .number-item:last-child {
  127. margin-right: 0;
  128. }
  129. </style>

  

如果大家有任何疑问即可留言反馈,会在第一时间回复反馈,谢谢大家!

本人使用GSAP框架搭建的个人网站也上线啦!有兴趣可以访问 zhaohongcheng.com 查看,感谢~

本人uni-app影视项目已经重磅开源,一套代码套发布到H5、APP、小程序等多个平台!有兴趣可以访问Dcloud官方插件市场https://ext.dcloud.net.cn/plugin?id=1839 查看,感谢~

本文为Tz张无忌文章,读后有收获可以请作者喝杯咖啡,转载请文章注明出处:https://www.cnblogs.com/zhaohongcheng/

Vue.js大屏数字滚动翻转效果的更多相关文章

  1. JS+CSS实现数字滚动

    最近在实现一个显示RGB颜色数值的动画效果时,尝试使用了writing-mode(书写模式)及 text-orientation来实现文字的竖直方向的排列,并借助CSS的transition(过渡)来 ...

  2. Vue.js大总结

    最近回顾了一下Vue.js的基础知识,把认为重要的几个点简单的罗列了出来 vue渐进式的理解 vue可以开发很多插件,可以把很多插件组合到一起,渐进的增加vue的功能 update beforeUpd ...

  3. 数字滚动动画效果 vue组件化

    参考了这篇文章,作者思路很清晰,简单做了下修改,蟹蟹作者,链接在此:https://www.jb51.net/css/685357.html#comments 主要思路是利用css属性writing- ...

  4. vue.js 首屏优化

    我们以 vue-cli 工具为例,使用 vue-router 搭建SPA应用,UI框架选用 element-ui , ajax方案选用 axios, 并引入 vuex ,使用 vuex-router- ...

  5. css&js实现顶部banner滚动提示效果

    以一个小例子来展示滚动提示的代码部分: try.html <div id="scrollobj" > <span class="scrollTxt&qu ...

  6. vue 实现 多个 数字滚动增加动效

    参考网上其他同学写的 具体出处忘了,不然一定贴上,有问题请联系. 图一是具体js代码:二是设置定时器:三是dom节点需要写ref numberGrow (ele) { this.summaryData ...

  7. 大屏FAQ

    1. 大屏可以分为哪几类?帆软有哪些大屏硬件合作商?编辑 拼接屏:通常由单个46-55寸的液晶显示屏组成屏幕墙,存在拼缝,借助矩阵.屏控系统来进行信号的输入与输出控制,可以实现屏幕墙上多个屏幕的组合. ...

  8. 使用rem配置PC端自适应大屏

    效果如下 使得大屏不论在什么宽高比例依然能展示全部数据 安装 npm install -S postcss-pxtorem rem配置思路 原先的rem函数是能解决大部分的问题的,如果展示不全,也可以 ...

  9. js标题文字向上滚动

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

随机推荐

  1. 使用C++代码打印数字正方形

    使用C++代码打印数字正方形 作为一名初学者,最近在跟着网课学习C++程序设计基础.在学习过程中遇到了一些习题,我根据自己的理解和思路写了一些代码实现,算是对自己学习过程的一个记录,也希望可以对别人有 ...

  2. .Net Core WebApi(三)在Linux服务器上部署

    鸽了好久,终于有个时间继续写了,继上一篇之后,又写(水)了一篇,有什么不足之处请大家指出,多谢各位了. 下面有两个需要用到的软件,putty和pscp,我已经上传到博客园了,下载请点击这里. 一.准备 ...

  3. 在移动硬盘中安装win10和macos双系统

    本文通过在SSD移动硬盘中安装win10和macos双系统,实现操作系统随身携带 小慢哥的原创文章,欢迎转载 目录 ▪ 目标 ▪ 准备工作 ▪ Step1. 清空分区,转换为GPT ▪ Step2. ...

  4. PHP输出A到Z及相关

    先看以下一段PHP的代码,想下输出结果是什么. <?php for($i='A'; $i<='Z'; $i++) { echo $i . '<br>'; } ?> 输出的 ...

  5. 运用wxs制作微信小程序左滑功能和跳转,性能更优越

    锲子 微信小程序自定义左滑功能加上跳转,换成以往,左滑功能的逻辑一般是在js中实现,但在拖动方面,性能并不是那么的流畅.如今,官方新扩展了一套脚本语言wxs,在IOS设备上运行,性能会比JS快2~20 ...

  6. RESTful基本概念

    文章目录 01 前言 02 RESTful的来源 03 RESTful6大原则 1. C-S架构 2. 无状态 3.统一的接口 4.一致的数据格式 4.系统分层 5.可缓存 6.按需编码.可定制代码( ...

  7. C语言1作业5

    问题 答案 这个作业属于那个课程 C语言程序设计1 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-2 我在这个课程的目的是 学习并掌握C ...

  8. Visual Studio Online 的 FAQ:iPad 支持、自托管环境、Web 版 VS Code、Azure 账号等

    北京时间 2019 年 11 月 4 日,在 Microsoft Ignite 2019 大会上,微软正式发布了 Visual Studio Online 公开预览版!发布之后,开发者们都为之振奋.同 ...

  9. nginx篇高级用法之基于TCP/UDP的四层调度

    nginx 从1.9版本开始支持基于TCP/UDP的四层调度,在编译nginx时使用--with-stream开启该模块 支持TCP/UDP调度时,支持给所有的软件做调度器,例如:nfs smb ft ...

  10. 详解SpringBoot应用跨域访问解决方案

    一.什么是跨域访问 说到跨域访问,必须先解释一个名词:同源策略.所谓同源策略就是在浏览器端出于安全考量,向服务端发起请求必须满足:协议相同.Host(ip)相同.端口相同的条件,否则访问将被禁止,该访 ...