vue3数字滚动动画

  • 1.新建组件vue-countTo.vue
  • 2.引入animationFrame.js
  • 3.页面上使用

1.新建组件vue-countTo.vue

<template><span>{{ state.displayValue }}</span>
</template><script setup>
import { onMounted, onUnmounted, reactive, watch, computed } from "vue";
import {requestAnimationFrame,cancelAnimationFrame,
} from "./animationFrame.js";const props = defineProps({start: {type: Number,required: false,default: 0,},end: {type: Number,required: false,default: 2021,},duration: {type: Number,required: false,default: 5000,},autoPlay: {type: Boolean,required: false,default: true,},decimals: {type: Number,required: false,default: 0,validator(value) {return value >= 0;},},decimal: {type: String,required: false,default: ".",},separator: {type: String,required: false,default: ",",},prefix: {type: String,required: false,default: "",},suffix: {type: String,required: false,default: "",},useEasing: {type: Boolean,required: false,default: true,},easingFn: {type: Function,default(t, b, c, d) {return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;},},
});const isNumber = (val) => {return !isNaN(parseFloat(val));
};// 格式化数据,返回想要展示的数据格式
const formatNumber = (val) => {if (props.default) {val = val.toFixed(props.default);val += '';const x = val.split('.');let x1 = x[0];const x2 = x.length > 1 ? props.decimal + x[1] : '';const rgx = /(\d+)(\d{3})/;if (props.separator && !isNumber(props.separator)) {while (rgx.test(x1)) {x1 = x1.replace(rgx, '$1' + props.separator + '$2');}}return props.prefix + x1 + x2 + props.suffix;} else {return Math.ceil(val);}
};// 相当于vue2中的data中所定义的变量部分
const state = reactive({localStart: props.start,displayValue: formatNumber(props.start),printVal: null,paused: false,localDuration: props.duration,startTime: null,timestamp: null,remaining: null,rAF: null,
});// 定义一个计算属性,当开始数字大于结束数字时返回true
const stopCount = computed(() => {return props.start > props.end;
});
// 定义父组件的自定义事件,子组件以触发父组件的自定义事件
const emits = defineEmits(["onMountedcallback", "callback"]);const startCount = () => {state.localStart = props.start;state.startTime = null;state.localDuration = props.duration;state.paused = false;state.rAF = requestAnimationFrame(count);
};watch(() => props.start,() => {if (props.autoPlay) {startCount();}}
);watch(() => props.end,() => {console.log(111);if (props.autoPlay) {startCount();}}
);
// dom挂在完成后执行一些操作
onMounted(() => {if (props.autoPlay) {startCount();}emits("onMountedcallback");
});
// 暂停计数
const pause = () => {cancelAnimationFrame(state.rAF);
};
// 恢复计数
const resume = () => {state.startTime = null;state.localDuration = +state.remaining;state.localStart = +state.printVal;requestAnimationFrame(count);
};const pauseResume = () => {if (state.paused) {resume();state.paused = false;} else {pause();state.paused = true;}
};const reset = () => {state.startTime = null;cancelAnimationFrame(state.rAF);state.displayValue = formatNumber(props.start);
};const count = (timestamp) => {if (!state.startTime) state.startTime = timestamp;state.timestamp = timestamp;const progress = timestamp - state.startTime;state.remaining = state.localDuration - progress;// 是否使用速度变化曲线if (props.useEasing) {if (stopCount.value) {state.printVal =state.localStart -props.easingFn(progress,0,state.localStart - props.end,state.localDuration);} else {state.printVal = props.easingFn(progress,state.localStart,props.end - state.localStart,state.localDuration);}} else {if (stopCount.value) {state.printVal =state.localStart -(state.localStart - props.end) * (progress / state.localDuration);} else {state.printVal =state.localStart +(props.end - state.localStart) * (progress / state.localDuration);}}if (stopCount.value) {state.printVal = state.printVal < props.end ? props.end : state.printVal;} else {state.printVal = state.printVal > props.end ? props.end : state.printVal;}state.displayValue = formatNumber(state.printVal);if (progress < state.localDuration) {state.rAF = requestAnimationFrame(count);} else {emits("callback");}
};
// 组件销毁时取消动画
onUnmounted(() => {cancelAnimationFrame(state.rAF);
});
</script>

2.引入animationFrame.js

let lastTime = 0
const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀let requestAnimationFrame
let cancelAnimationFrame// 判断是否是服务器环境
const isServer = typeof window === 'undefined'
if (isServer) {requestAnimationFrame = function() {return}cancelAnimationFrame = function() {return}
} else {requestAnimationFrame = window.requestAnimationFramecancelAnimationFrame = window.cancelAnimationFramelet prefix// 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式for (let i = 0; i < prefixes.length; i++) {if (requestAnimationFrame && cancelAnimationFrame) { break }prefix = prefixes[i]requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame']cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] || window[prefix + 'CancelRequestAnimationFrame']}// 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeoutif (!requestAnimationFrame || !cancelAnimationFrame) {requestAnimationFrame = function(callback) {const currTime = new Date().getTime()// 为了使setTimteout的尽可能的接近每秒60帧的效果const timeToCall = Math.max(0, 16 - (currTime - lastTime))const id = window.setTimeout(() => {callback(currTime + timeToCall)}, timeToCall)lastTime = currTime + timeToCallreturn id}cancelAnimationFrame = function(id) {window.clearTimeout(id)}}
}export { requestAnimationFrame, cancelAnimationFrame }

3.页面上使用

  <countTo :end='end' :autoPlay="true" :duration='3000'  />

vue3数字滚动动画相关推荐

  1. qt同时两个动画执行_Qt实现数字滚动动画效果

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html Qt实现数字滚动动画效果 3. ...

  2. android 数字滚动抽奖_Android TextView自定义数字滚动动画

    背景 在开发需求当中,当有总收益.总用户数等数字要显示时,为了更好的给用户提供展示效果,往往会想加入炫酷的数字滚动动画,使呆板平静的数字变得灵活起来,给人一种增值的直观感受. 简介 NumberRol ...

  3. 微信小程序使用数字滚动动画

    实现思路 为了实现数字的无限滚动效果,每个数字框的内部,其实包含了两组0~9的view,每个View的高度都一样 数字框内使用绝对定位,通过调整top位置,显示出指定的数字 使用transtion动画 ...

  4. 微信小程序 -数字滚动动画

    效果图 实现思路 为了实现数字的无限滚动效果,每个数字框的内部,其实包含了两组0~9的view,每个View的高度都一样 数字框内使用绝对定位,通过调整top位置,显示出指定的数字 使用transti ...

  5. vue简单的数字滚动动画

    vue简单的数字滚动,使用transform:translateY()来实现滚动,简陋且粗暴 效果 代码 <div><div class="record"> ...

  6. html数字滚动动画效果,高效的jquery数字滚动特效

    本文实例讲述了基于jquery数字滚动特效的代码,分为四种情况分享给大家供大家参考,具体如下: 有分隔符,有小数点: 只有分隔符: 只有小数点: 无分隔符,无小数点: 运行效果图: 具体代码如下 数字 ...

  7. android数字滚动动画,数字滚动效果 RollingText

    RollingTextView 特性 使用简单,API与TextView类似,setText方法可带有上下滚动的动画 支持xml设置android:textSize/android:textColor ...

  8. vue 数字动画递增_数字滚动动画效果 vue组件化

    主要思路是利用css属性writing-mode:vertical-lr:通过设定最大字符长度,补零,去循环,然后添加style translate和transition来完成想要的效果: 子组件根据 ...

  9. android数字滚动动画,Android超简单实现金钱滚动效果

    目录 目录 效果展示 实现原理 利用ValueAnimator将数值从0一直增长到你所需要展示的数值,然后使用TextView将增长过程中的数值不断展示即可实现金钱的滚动效果. ValueAnimat ...

最新文章

  1. matlab立方体投影,那些投影到三维的高维立方体,后来都怎么样了?(浅度好文)...
  2. 从 no-code 到 low-code 再到 pro-code
  3. 一起谈.NET技术,通过16道练习学习Linq和Lambda
  4. html网页访问WebAPI中的方法遇到的问题
  5. php 动态显示数字,php – 如何动态创建具有指定数字的图像?
  6. pay-as-you-go
  7. python找指定内容_python查找指定具有相同内容文件的方法
  8. 有三个数a,b,c,要求按大小顺序输出。
  9. Tomcat优化实践——网站运维
  10. android常用的存储方式,Android数据的四种存储方式
  11. 互联网巨头竞逐客户端软件
  12. c语言怎么学自学,初学者如何学习c语言,带你玩转C语言
  13. 股票量化交易这些劣势你知道吗?
  14. creo三维生成二维图_proe5.0三维图转二维图
  15. 用rtl8139网卡制作的bios编程器(不用并口)
  16. C语言自制简单点菜系统
  17. 手机的 32K,26M时钟电路作用 (转载于 52rd zsqt8888的专栏)
  18. Ristretto:面向硬件的卷积神经网络逼近
  19. windbg wt命令
  20. “数字孪生城市”的概念,你知道多少?

热门文章

  1. 终于等来《仙剑奇侠传四》,全新阵容太可了!
  2. 7月火影忍者服务器维护,火影忍者手游7月13日维护更新内容及活动大全汇总
  3. 简陋的spring cloud搭建并部署云服务器
  4. 推荐 8 个支持 Vue3 的前端 UI 组件库,免费开源、漂亮美观,涵盖常用的业务组件
  5. 点九图完全解析-附官方工具
  6. spring-bean对象创建销毁顺序depend-on 干预
  7. 从月薪4000到年薪100万,我总结了2点
  8. 跳槽意愿报告:跳槽不太难,钱是原动力
  9. Android开源之仿微信UI
  10. 微信小程序-初始导航页面