Vue.js大屏数字滚动翻转效果
大屏数字滚动翻转效果来源于最近工作中element后台管理页面一张大屏的UI图,该UI图上有一个模块需要有数字往上翻动的效果,以下是最终实现的效果:
整体思路:
在实现此效果之前,我们先来捋一下思路,用思维导图来设计一下我们的实现步骤,如下:
你可以审查元素,下载数字背景图片,复制图片地址,或者使用其他背景图片、背景颜色
有了以上的设计流程,我们先来简单实现一下:
- // 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>
实现以上代码后,它的效果将是下面这样的:
思考:背景框中有了数字以后,我们现在来思考一下,背景框中的文字,一定是 0-9
之前的数字,要在不打乱以上 html
结构的前提下,如何让数字滚动起来呢?这个时候我们的魔爪就伸向了一个 CSS
属性: writing-mode
,下面是它属性的介绍:
- horizontal-tb:默认值,表示水平排版,从上到下。
- vertical-lr:表示垂直排版,从左到右。
- vertical-rl:表示垂直排版,从右到左。
它的实时效果是像下面这样:
根据以上的灵感,我们可以实现下面这样的效果:
代码如下:
- // 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
,它的效果如下:
代码加上 `transform: `translate(-50%,-${number * 10}%)`,示例如下
- .box-item span {
- position: absolute;
- top: 10px;
- left: 50%;
- transform: translate(-50%,-50%);
- letter-spacing: 10px;
- }
滚动动画的实现
在知道了每一个数字具体的滚动距离后,我们来设计一下,让数字能够随机滚动起来:
一下是让数字随机滚动的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;
- }
- }
- }
页面渲染效果:
数字随机增长,模拟轮询效果
页面渲染完毕后,我们来让数字滚动起来,设计如下两个方法,其中 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}%)`
- }
- }
最终实现效果:
完整代码如下:
- <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.$nextTick(() => {
- this.toOrderNum(1213123) // 这里输入数字即可调用
- this.setNumberTransform()
- })
- },
- 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>
如果大家有任何疑问即可留言反馈,会在第一时间回复反馈,谢谢大家!
本人使用GSAP框架搭建的个人网站也上线啦!有兴趣可以访问 zhaohongcheng.com 查看,感谢~
本人uni-app影视项目已经重磅开源,一套代码套发布到H5、APP、小程序等多个平台!有兴趣可以访问Dcloud官方插件市场https://ext.dcloud.net.cn/plugin?id=1839 查看,感谢~
本文为Tz张无忌文章,读后有收获可以请作者喝杯咖啡,转载请文章注明出处:https://www.cnblogs.com/zhaohongcheng/
Vue.js大屏数字滚动翻转效果的更多相关文章
- JS+CSS实现数字滚动
最近在实现一个显示RGB颜色数值的动画效果时,尝试使用了writing-mode(书写模式)及 text-orientation来实现文字的竖直方向的排列,并借助CSS的transition(过渡)来 ...
- Vue.js大总结
最近回顾了一下Vue.js的基础知识,把认为重要的几个点简单的罗列了出来 vue渐进式的理解 vue可以开发很多插件,可以把很多插件组合到一起,渐进的增加vue的功能 update beforeUpd ...
- 数字滚动动画效果 vue组件化
参考了这篇文章,作者思路很清晰,简单做了下修改,蟹蟹作者,链接在此:https://www.jb51.net/css/685357.html#comments 主要思路是利用css属性writing- ...
- vue.js 首屏优化
我们以 vue-cli 工具为例,使用 vue-router 搭建SPA应用,UI框架选用 element-ui , ajax方案选用 axios, 并引入 vuex ,使用 vuex-router- ...
- css&js实现顶部banner滚动提示效果
以一个小例子来展示滚动提示的代码部分: try.html <div id="scrollobj" > <span class="scrollTxt&qu ...
- vue 实现 多个 数字滚动增加动效
参考网上其他同学写的 具体出处忘了,不然一定贴上,有问题请联系. 图一是具体js代码:二是设置定时器:三是dom节点需要写ref numberGrow (ele) { this.summaryData ...
- 大屏FAQ
1. 大屏可以分为哪几类?帆软有哪些大屏硬件合作商?编辑 拼接屏:通常由单个46-55寸的液晶显示屏组成屏幕墙,存在拼缝,借助矩阵.屏控系统来进行信号的输入与输出控制,可以实现屏幕墙上多个屏幕的组合. ...
- 使用rem配置PC端自适应大屏
效果如下 使得大屏不论在什么宽高比例依然能展示全部数据 安装 npm install -S postcss-pxtorem rem配置思路 原先的rem函数是能解决大部分的问题的,如果展示不全,也可以 ...
- js标题文字向上滚动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
随机推荐
- 使用C++代码打印数字正方形
使用C++代码打印数字正方形 作为一名初学者,最近在跟着网课学习C++程序设计基础.在学习过程中遇到了一些习题,我根据自己的理解和思路写了一些代码实现,算是对自己学习过程的一个记录,也希望可以对别人有 ...
- .Net Core WebApi(三)在Linux服务器上部署
鸽了好久,终于有个时间继续写了,继上一篇之后,又写(水)了一篇,有什么不足之处请大家指出,多谢各位了. 下面有两个需要用到的软件,putty和pscp,我已经上传到博客园了,下载请点击这里. 一.准备 ...
- 在移动硬盘中安装win10和macos双系统
本文通过在SSD移动硬盘中安装win10和macos双系统,实现操作系统随身携带 小慢哥的原创文章,欢迎转载 目录 ▪ 目标 ▪ 准备工作 ▪ Step1. 清空分区,转换为GPT ▪ Step2. ...
- PHP输出A到Z及相关
先看以下一段PHP的代码,想下输出结果是什么. <?php for($i='A'; $i<='Z'; $i++) { echo $i . '<br>'; } ?> 输出的 ...
- 运用wxs制作微信小程序左滑功能和跳转,性能更优越
锲子 微信小程序自定义左滑功能加上跳转,换成以往,左滑功能的逻辑一般是在js中实现,但在拖动方面,性能并不是那么的流畅.如今,官方新扩展了一套脚本语言wxs,在IOS设备上运行,性能会比JS快2~20 ...
- RESTful基本概念
文章目录 01 前言 02 RESTful的来源 03 RESTful6大原则 1. C-S架构 2. 无状态 3.统一的接口 4.一致的数据格式 4.系统分层 5.可缓存 6.按需编码.可定制代码( ...
- C语言1作业5
问题 答案 这个作业属于那个课程 C语言程序设计1 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-2 我在这个课程的目的是 学习并掌握C ...
- Visual Studio Online 的 FAQ:iPad 支持、自托管环境、Web 版 VS Code、Azure 账号等
北京时间 2019 年 11 月 4 日,在 Microsoft Ignite 2019 大会上,微软正式发布了 Visual Studio Online 公开预览版!发布之后,开发者们都为之振奋.同 ...
- nginx篇高级用法之基于TCP/UDP的四层调度
nginx 从1.9版本开始支持基于TCP/UDP的四层调度,在编译nginx时使用--with-stream开启该模块 支持TCP/UDP调度时,支持给所有的软件做调度器,例如:nfs smb ft ...
- 详解SpringBoot应用跨域访问解决方案
一.什么是跨域访问 说到跨域访问,必须先解释一个名词:同源策略.所谓同源策略就是在浏览器端出于安全考量,向服务端发起请求必须满足:协议相同.Host(ip)相同.端口相同的条件,否则访问将被禁止,该访 ...