num-auto-add:数字自增动画
序言
我们经常在一些好的网站上遇到数字自增的动画效果,为用户提供了更加丰富的交互体验,看起来非常酷。
我之前也有写过,为了方便以后使用,打算将它优化,并上传到npm中。
首先第一步,就是将代码交给chatGPT优化。
可以发现,除了定时器的时间间隔变了,并没有多的变化
继续让chatGPT优化,此时它把用定时器实现动画效果改成用requestAnimationFrame来实现,动画效果更加丝滑了,真不错。
看它输出一大堆,以为很牛逼,然而一运行代码,结果都跑不起来。
总的来说,chatGPT目前只能辅助写代码,逻辑稍微复杂一点就会出错,包括代码的注释都是有问题的,还是得靠自己修修改改。
最终小demo的地址为:num-auto-add - npm (npmjs.com) ,欢迎各位大佬下载使用。
使用教程(vue项目中使用举例)
1.下载包
- 用yarn下载
yarn add num-auto-add
- 用npm下载
npm i num-auto-add
2.引入包
import numAutoAdd from "num-auto-add";
3.声明自定义指令
Vue.directive('numAutoAdd', numAutoAdd());
注意:numAutoAdd可以函数接收两个参数
- 第一个参数是设置动画执行的总时间(以毫秒为单位),默认是700ms
- 第二个参数是布尔标志many,用于指示动画是可以执行多次还是只执行一次,默认为true,也就是可以执行多次。
4.给数字绑定指令
到此,就实现数字自增效果了,使用起来非常简单
实现原理
源代码如下:
export default function(totalTime = 700, many = true) {
function animateNumber(el, finalNum, startTime) {
const currentTime = Date.now();
const runTime = currentTime - startTime; // 运行时间
const progress = Math.min(runTime / totalTime, 1); // 动画进度
el.innerHTML = Math.floor(finalNum * progress); // 当前页面显示的数字
if (runTime < totalTime) {
requestAnimationFrame(() => animateNumber(el, finalNum, startTime));
}
}
return {
// 当被绑定的元素插入到 DOM 时调用
inserted: function(el, binding) {
// flag用来判断是否能执行动画,防止一个时间段内触发多次动画函数
binding.flag = true;
// 元素在可视区域内才开始执行动画的函数
binding.animate = () => {
// 获取元素距离可视区域顶部的距离
const top = el.getBoundingClientRect().top;
// 获取浏览器可视区域的高度(这里考虑了浏览器兼容的问题)
const h =
document.documentElement.clientHeight || document.body.clientHeight;
// 当元素在可视区域内
if (top < h) {
// 如果动画没在执行
if (binding.flag) {
binding.flag = false;
const finalNum = el.innerHTML; // 要显示的真实数值
animateNumber(el, finalNum, Date.now()); // 执行数字自增动画
// 如果只执行一次动画,则解绑滚动事件
!many && window.removeEventListener("scroll", binding.animate);
}
} else {
binding.flag = true;
}
};
window.addEventListener("scroll", binding.animate);
},
// 自定义绑定的组件销毁时,关闭监听器
unbind: function(el, binding) {
window.removeEventListener("scroll", binding.animate);
}
};
}
inserted
inserted 属性是一个函数,当元素被插入到 DOM 中时调用。给window添加滚动事件,而回调函数为animate,每次滚动鼠标,都会执行这个函数。
window.removeEventListener("scroll", binding.animate)
animate 函数会检查元素是否出现在可视区域。一旦元素进入视口,就会调用“数字自增动画”animateNumber
if (top < h) {
// 如果动画没在执行
if (binding.flag) {
binding.flag = false;
const finalNum = el.innerHTML; // 要显示的真实数值
animateNumber(el, finalNum, Date.now()); // 执行数字自增动画
// 如果只执行一次动画,则解绑滚动事件
!many && window.removeEventListener("scroll", binding.animate);
}
animateNumber是一个函数,会计算动画的进度并更新元素的当前值。
function animateNumber(el, finalNum, startTime) {
const currentTime = Date.now();
const runTime = currentTime - startTime; // 运行时间
const progress = Math.min(runTime / totalTime, 1); // 动画进度
el.innerHTML = Math.floor(finalNum * progress); // 当前页面显示的数字
if (runTime < totalTime) {
requestAnimationFrame(() => animateNumber(el, finalNum, startTime));
}
}
unbind
unbind 属性是一个函数,自定义绑定的组件销毁时调用。此函数将解绑滚动事件,避免占用资源。
// 自定义绑定的组件销毁时,关闭监听器
unbind: function(el, binding) {
window.removeEventListener("scroll", binding.animate);
}
总结
chatGPT在编程方面的成就是非常显著的,它不仅开创了人机交互的新时代,也为技术的发展带来了新的思路和方法,使用chatGPT辅助写代码是大势所趋。另外,它还能辅助我们写文章,例如,该文章的部分内容就是使用AI生成的。