前端开发
Vue3实现超级有趣的功能:数字增长动画!!
发布时间:2024-04-19 16:33:55 浏览量:63
平时浏览一些跟数字有关的网页的时候,可能你会发现数字并不是直接从 0 变成 99999 的,这样会很生硬,而是会有一个从 0 增长到 99999 的动画效果,如下图:
那这个效果要怎么实现呢?其实挺简单的,也挺有趣的,继续往下看吧~
useNumberAnimation
我们创建一个文件 use-number-animation.ts 来写这个 hooks
确定参数
首先来确定这个函数需要接受什么参数:
from:起始数字
to:最终数字
duration:动画延迟间隔
onProgress:增长回调函数
// from 起始数字
// to 最终数字
// duration 延迟间隔(ms)
// onProgress 更新回调函数
export const useNumberAnimation =(options:
from: number;
to:number;
duration: number;
onProgress?:(v:number)=>void;
12 })=>{};
requestAnimationFrame
可以看到数字是在不停变化的,所以我们需要有一个定时任务去让这个数字一直变化才行,那么用 setInterval 吗?不是的,显然用 requestAnimationFrame 性能会更佳,它会在浏览器下一帧重绘之前执行~
//use-number-animation.ts
// from 起始数字
// to 最终数字
// duration 延迟间隔(ms)
// onProgress 更新回调函数
export const useNumberAnimation=(options:{
from: number;
to: number;
duration: number;
onProgress?:(v:number)=>void;
})=>{
const {from,to,duration,onProgress }= options;
const run =()=>{
// 继续执行
requestAnimationFrame(run);
};
run();
};
增长速度要怎么算
可以看到数字在不断增长,那么既然是增长,就需要计算增长速度,增长速度要怎么算呢?
假设我要用3000ms的时间去从0增长到378291.668,那增长速度是不是 (378291.668 - 0) / 3000呢?
由此我们可以知道增长速度 speed = (to - from) / duration;
const {from, to, duration, onProgress }= options;
let value:number=from;
// 算出增长速度
const speed=(to-from)/duration;
啥时候终止数字的增长?
其实很简单,那就是从开始增长开始,经过的时间大于 duration 时,就终止,这个时候说明动画必须要结束的~
最终代码
可以得出最终的代码为
// use-number-animation.ts
// from 起始数字
// to 最终数字
// duration 延迟间隔(ms)
// onProgress 更新回调函数
export const useNumberAnimation= (options:{
from: number;
to: number;
duration:number;
onProgress?:(v:number)=>void;
})=>{
const {from, to, duration, onProgress }= options;
let value:number =from;
// 算出增长速度
const speed=(to-from)/duration;
// 起始时间
const startTime = Date.now();
const run=()=>{
//时间间隔
const t=Date.now()-startTime;
//当时间间隔大于延迟时间时终止
if(t >= duration){
value = to;
onProgress?.(value);
return;
}
// 当前值 = 起始值 + 时间间隔 *增长速度
value =from +t*speed;
onProgress?.(value);
//继续执行
requestAnimationFrame(run);
};
run();
};
使用方式如下
<template>
<div class="flex justify-center">{{ num }}</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useNumberAnimation } from './use-number-animation';
const num = ref('0');
useNumberAnimation({
from:0,
to:378291.668,
duration:3000,
onProgress:v=>{
console.log('此时的值是:${v}');
num.value =v.toFixed(2);
},
});
</script>