我们在生活中肯定看到过这样的场景,在我们进入页面或者刷新页面的时候数字(金额)会从高到低的一个动画效果;那么这是怎么做的呢?最开始的时候我以为是用css3来做的;后来看了别人的教程才发现,原来是用js写的;我没有完全按照教程的来,我用到的是Hz为60来计算的,教程是根据时间;大致思路是差不多的
需求分析
既然我们知道是用JS来做的,那么肯定是去变化数字了;既然我们要做到这几点,那么肯定是需要封装一些参数的
- 时间 duration:指在此动画期间的一个事件间隔
- from 起始值:值我们从某一个值开始动画
- to 目标值:值这是我们最终的一个值
- onProgress 回调函数:每次得到值以后的一个回调,便于得到数据渲染
注意:
这儿用到了window.requestAnimationFrame方法,然后在其中回调函数执行次数通常是每秒 60 次;下面代码中用到了此逻辑
代码分析
- 将duration(毫秒)转为秒
- 由于requestAnimationFrame有60Hz(每秒执行60次),所以将秒乘60并取整就可以得到每秒执行多少次
- 然后dis计算出起始值和目标值差值多少
- 差值除以每秒执行多少次,也就得到了步长
- 在每次执行动画的时候都将得到的步长和初始值相加即可
- 最后就是根据相对于的条件停止即可
模仿写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.number {
font-weight: 700;
font-size: 36px;
width: 300px;
margin: 100px auto;
}
</style>
</head>
<body>
<div class="number"></div>
<script>
const number = document.querySelector('.number');
/**
* duration:秒
* from:来源值
* to:目标值
* onProgress:回调函数
**/
function animation(duration, from, to, onProgress) {
var start = new Date().getTime()
let dur = (duration) / 1000;
let frequency = Math.floor(dur * 60); // 每次
const dis = to - from; // 差值
console.log(dis);
const speed = Math.ceil(dis / frequency); // 步长
console.log(speed);
let value = from; // 当前的值
let d = from - to; // 初始值
function _run() {
var end = new Date().getTime()
if (d <= to) {
value = to;
onProgress(value);
console.log('cost is', `${end - start}ms`)
return;
};
d = d + speed; // 相减
value = d;
onProgress(value);
requestAnimationFrame(_run);
};
requestAnimationFrame(_run);
};
animation(2000,2299,299,(val)=>{
number.innerHTML = `<span style="color:red">${val}</span>`;
})
</script>
</body>
</html>
网上教程
效果代码:个人感觉跟我写的差不多,数字会跑很快;感觉都都看不清了;我模仿的写法也是这样。
- 完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.number {
font-weight: 700;
font-size: 36px;
width: 300px;
margin: 100px auto;
}
</style>
</head>
<body>
<div class="number"></div>
<script>
const number = document.querySelector('.number');
/**
* duration:秒
* from:来源值
* to:目标值
* onProgress:回调函数
**/
function animation(duration, from, to, onProgress) {
const dis = to - from; // 差值
const speed = dis / duration; // 步长
const startTime = Date.now();
let value = from; // 当前的值
onProgress(value);
function _run() {
const now = Date.now();
const time = now - startTime;
if (time >= duration) {
value = to;
onProgress(value);
return;
};
const d = Math.floor(time * speed);
value = from + d;
onProgress(value);
requestAnimationFrame(_run);
};
requestAnimationFrame(_run);
};
animation(1000,1099,299,(val)=>{
number.textContent = val.toFixed(2);
})
</script>
</body>
</html>
修改后的效果
增加了一个判断; 如代码所示,每次执行一次动画的时候+1,执行6次以后再进行回调展示数据,就不会展示那么频繁,从而导致数据模糊效果了。
往期文章
-
css登录按钮炫酷效果
-
css是你永远学不会的语言
-
electron 中使用本地数据库
-
electron 中 webview的使用
-
前端使用electron+vue3+ts搭建一个桌面端应用且可以热更新
-
electron+vue3+ts开发了一个JSON工具桌面软件
-
element-ui动态级联选择器回显问题,二十多行代码就可以搞定
-
小程序云开发,通过云函数进行云开发
-
原生js实现瀑布流效果
-
uniapp中的请求接口封装