Vue.js实现大屏数字滚动翻转效果


Posted in Javascript onNovember 29, 2019

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

Vue.js实现大屏数字滚动翻转效果

整体思路:

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

Vue.js实现大屏数字滚动翻转效果

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

Vue.js实现大屏数字滚动翻转效果

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

// CSS代码
<style>
.box-item {
 position: relative;
 display: inline-block;
 width: 54px;
 height: 82px;
 /* 背景图片 */
 background: url(./number-bg.png) no-repeat center center;
 background-size: 100% 100%;
 font-size: 62px;
 line-height: 82px;
 text-align: center;
}
</style>

// htm代码
<div class="box">
 <p class="box-item">
 <span>1</span>
 </p>
</div>

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

Vue.js实现大屏数字滚动翻转效果

思考:

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

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

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

Vue.js实现大屏数字滚动翻转效果

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

Vue.js实现大屏数字滚动翻转效果

代码如下:

// html部分
<p class="box-item">
 <span>0123456789</span>
</p>

// style部分
.box-item {
 display: inline-block;
 width: 54px;
 height: 82px;
 background: url(./number-bg.png) no-repeat center center;
 background-size: 100% 100%;
 font-size: 62px;
 line-height: 82px;
 text-align: center;
 position: relative;
 writing-mode: vertical-lr;
 text-orientation: upright;
 /* overflow: hidden; */
}
.box-item span {
 position: absolute;
 top: 10px;
 left: 50%;
 transform: translateX(-50%);
 letter-spacing: 10px;
}

计算滚动

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

答案是:向下滚动-50%

那么其他的数字呢?

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

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

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

Vue.js实现大屏数字滚动翻转效果

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

.box-item span {
 position: absolute;
 top: 10px;
 left: 50%;
 transform: translate(-50%,-50%);
 letter-spacing: 10px;
}

滚动动画的实现

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

Vue.js实现大屏数字滚动翻转效果

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

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

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

完善

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

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

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

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

渲染

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

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

// html代码
<ul>
 <li
 :class="{'number-item': !isNaN(item) }"
 v-for="(item,index) in computeNumber"
 :key="index"
 >
 <span v-if="!isNaN(item)">
  <i ref="numberItem">0123456789</i>
 </span>
 <span v-else>{{item}}</span>
 </li>
</ul>


// CSS代码
.number-item {
 width: 50px;
 background: url(./number-bg.png) no-repeat center center;
 background-size:100% 100%;
 & > span {
 position: relative;
 display: inline-block;
 margin-right: 10px;
 width: 100%;
 height: 100%;
 writing-mode: vertical-rl;
 text-orientation: upright;
 overflow: hidden;
 & > i {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%,0);
  transition: transform 0.5s ease-in-out;
  letter-spacing: 10px;
 }
 }
}

页面渲染效果:

Vue.js实现大屏数字滚动翻转效果

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

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

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

最终实现效果:

Vue.js实现大屏数字滚动翻转效果

完整代码如下:

<template>
 <div class="chartNum">
    <h3 class="orderTitle">订单总量</h3>
    <div class="box-item">
     <li :class="{'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
      v-for="(item,index) in orderNum"
      :key="index">
       <span v-if="!isNaN(item)">
        <i ref="numberItem">0123456789</i>
       </span>
      <span class="comma" v-else>{{item}}</span>
     </li>
    </div>
   </div>
</template>
<script>
 export default {
  data() {
   return {
    orderNum: ['0', '0', ',', '0', '0', '0', ',', '0', '0', '0'], // 默认订单总数
   }
  }
  mounted: {
   this.toOrderNum(num) // 这里输入数字即可调用
  },
  methods: {
    // 设置文字滚动
   setNumberTransform () {
    const numberItems = this.$refs.numberItem // 拿到数字的ref,计算元素数量
    const numberArr = this.orderNum.filter(item => !isNaN(item))
    // 结合CSS 对数字字符进行滚动,显示订单数量
    for (let index = 0; index < numberItems.length; index++) {
    const elem = numberItems[index]
    elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`
    }
   },
   // 处理总订单数字
   toOrderNum(num) {
    num = num.toString()
    // 把订单数变成字符串
    if (num.length < 8) {
    num = '0' + num // 如未满八位数,添加"0"补位
    this.toOrderNum(num) // 递归添加"0"补位
    } else if (num.length === 8) {
    // 订单数中加入逗号
    num = num.slice(0, 2) + ',' + num.slice(2, 5) + ',' + num.slice(5, 8)
    this.orderNum = num.split('') // 将其便变成数据,渲染至滚动数组
    } else {
    // 订单总量数字超过八位显示异常
    this.$message.warning('订单总量数字过大,显示异常,请联系客服')
    }
   },
  }
 }
</script>
<style scoped lang='scss'>
  /*订单总量滚动数字设置*/
 .box-item {
  position: relative;
  height: 100px;
  font-size: 54px;
  line-height: 41px;
  text-align: center;
  list-style: none;
  color: #2D7CFF;
  writing-mode: vertical-lr;
  text-orientation: upright;
  /*文字禁止编辑*/
  -moz-user-select: none; /*火狐*/
  -webkit-user-select: none; /*webkit浏览器*/
  -ms-user-select: none; /*IE10*/
  -khtml-user-select: none; /*早期浏览器*/
  user-select: none;
  /* overflow: hidden; */
 }
 /* 默认逗号设置 */
 .mark-item {
  width: 10px;
  height: 100px;
  margin-right: 5px;
  line-height: 10px;
  font-size: 48px;
  position: relative;
  & > span {
   position: absolute;
   width: 100%;
   bottom: 0;
   writing-mode: vertical-rl;
   text-orientation: upright;
  }
 }
 /*滚动数字设置*/
 .number-item {
  width: 41px;
  height: 75px;
  background: #ccc;
  list-style: none;
  margin-right: 5px;
  background:rgba(250,250,250,1);
  border-radius:4px;
  border:1px solid rgba(221,221,221,1);
  & > span {
   position: relative;
   display: inline-block;
   margin-right: 10px;
   width: 100%;
   height: 100%;
   writing-mode: vertical-rl;
   text-orientation: upright;
   overflow: hidden;
   & > i {
    font-style: normal;
    position: absolute;
    top: 11px;
    left: 50%;
    transform: translate(-50%,0);
    transition: transform 1s ease-in-out;
    letter-spacing: 10px;
   }
  }
 }
 .number-item:last-child {
  margin-right: 0;
 }
</style>

总结

以上所述是小编给大家介绍的Vue.js实现大屏数字滚动翻转效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
定义select的边框颜色
Apr 28 Javascript
基于Jquery制作的幻灯片图集效果打包下载
Feb 12 Javascript
关于include标签导致js路径找不到的问题分析及解决
Jul 09 Javascript
深入理解JS中的变量及作用域、undefined与null
Mar 04 Javascript
了不起的node.js读书笔记之例程分析
Dec 22 Javascript
举例讲解AngularJS中的模块
Jun 17 Javascript
基于Node.js的强大爬虫 能直接发布抓取的文章哦
Jan 10 Javascript
BootStrap selectpicker后台动态绑定数据
Jun 01 Javascript
vue.js如何将echarts封装为组件一键使用详解
Oct 10 Javascript
JS实现的检验身份证格式并输出出生日期,年龄,性别,出生地示例
May 17 Javascript
vue中使用element组件时事件想要传递其他参数的问题
Sep 18 Javascript
JS实现简单日历特效
Jan 03 Javascript
Vue基础配置讲解
Nov 29 #Javascript
jQuery实现弹幕特效
Nov 29 #jQuery
Vue实现多标签选择器
Nov 28 #Javascript
swiper实现异形轮播效果
Nov 28 #Javascript
Vue请求java服务端并返回数据代码实例
Nov 28 #Javascript
javascript实现异形滚动轮播
Nov 28 #Javascript
javascript实现切割轮播效果
Nov 28 #Javascript
You might like
php4的session功能评述(二)
2006/10/09 PHP
PHP下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
2011/06/09 PHP
浅析Dos下运行php.exe,出现没有找到php_mbstring.dll 错误的解决方法
2013/06/29 PHP
php解析url的三个示例
2014/01/20 PHP
php简单复制文件的方法
2016/05/09 PHP
jQuery(1.3.2) 7行代码搞定跟随屏幕滚动的层
2009/05/21 Javascript
JavaScript中String和StringBuffer的速度之争
2010/04/01 Javascript
基于jquery的实现简单的表格中增加或删除下一行
2010/08/01 Javascript
JavaScript内核之基本概念
2011/10/21 Javascript
javascript中为某个元素指定事件的三种方式
2014/08/07 Javascript
JavaScript实现点击自动选择TextArea文本的方法
2015/07/02 Javascript
vue 2.0项目中如何引入element-ui详解
2017/09/06 Javascript
javascript基本常用排序算法解析
2017/09/27 Javascript
使用layui实现的左侧菜单栏以及动态操作tab项方法
2019/09/10 Javascript
vue+element表格导出为Excel文件
2019/09/26 Javascript
vue实现微信浏览器左上角返回按钮拦截功能
2020/01/18 Javascript
Node使用koa2实现一个简单JWT鉴权的方法
2021/01/26 Javascript
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
python 多线程实现检测服务器在线情况
2015/11/25 Python
Python 通过pip安装Django详细介绍
2017/04/28 Python
Python书单 不将就
2017/07/11 Python
python中日志logging模块的性能及多进程详解
2017/07/18 Python
Selenium(Python web测试工具)基本用法详解
2018/08/10 Python
python使用response.read()接收json数据的实例
2018/12/19 Python
Python 进程之间共享数据(全局变量)的方法
2019/07/16 Python
详解python中__name__的意义以及作用
2019/08/07 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
python def 定义函数,调用函数方式
2020/06/02 Python
偷看我的初中毕业鉴定
2014/01/29 职场文书
省级青年文明号申报材料
2014/05/23 职场文书
知识就是力量演讲稿
2014/09/13 职场文书
整改报告怎么写
2014/11/06 职场文书
优秀英文求职信范文
2015/03/19 职场文书
经济纠纷起诉状
2015/05/20 职场文书
详解jQuery的核心函数和事件处理
2022/02/18 jQuery
JS实现简单九宫格抽奖
2022/06/28 Javascript