# 效果图
# 代码
<template>
<label style="position: relative;">
<div class="lbut" @click="convertedFunc">
{{ count }} click and i will do the last time</div>
<div ref="shader" class="lshader"></div>
</label>
</template>
<script setup>
import {
ref,
} from 'vue';
const count = ref(0);
const shader = ref(null);
const doLastTimeFunc = (func, time = 2000) => {
let n = null
return () => {
clearTimeout(n)
n = setTimeout(() => {
func();
}, time)
}
}
const doClick = () => {
count.value++;
}
const convertedFunc = doLastTimeFunc(doClick)
</script>
<style scoped>
label {
overflow: hidden;
display: block;
height: 34px;
width: 284px;
border-radius: 1em;
}
.lbut {
display: flex;
justify-content: center;
position: relative;
width: 280px;
height: 30px;
margin-left: 2px;
margin-top: 2px;
font-weight: bolder;
background-color: black;
color: white;
border-radius: 1em;
cursor: pointer;
z-index: 1;
}
.lbut:hover {
background-color: white;
color: black;
}
.lshader {
position: absolute;
top: -142px;
left: -2px;
height: 300px;
width: 300px;
border-radius: 1em;
background: conic-gradient(from 180deg at 50% 50%, #00D1FF 0deg, #EE27FF 106.88deg, #205EFF 206.25deg, #00F0FF 286.87deg, #00D1FF 360deg);
animation: rotate 3s linear infinite;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
# 学习点
当学习了闭包后,我们可以封装一个独立的变量到函数中重复使用,例如在函数中return函数
并使用外部函数的内部变量,此时返回出的函数同一个函数实例会拥有一个独立的外部变量,可以理解为形参,当触发这个返回方法实例总是会修改同一个函数变量,类似于这个变量永远为一个函数实例服务,也叫内存泄漏
。
- 一个小知识:如果使用
setTimeout或Interval
在设置的时间间隔过小时会产生 js 来不及找到 dom 的 bug,这个 bug 大致原因是操作 dom 时下一个操作又要进入,因此最好使用requestAnimationFrame
这个新的 api,这个 api 会自动寻找下一次渲染时机,因此所有由数值控制的移动,例如鼠标动画,或循环动画应该都由这个 api 接管,这样可以保证动画的流畅。注意这个 api 大致每秒执行 60 次,因此不必担心流畅程度,只需要控制好数值来让动画尽量以合适速度进行。
# 如何减缓requestAnimationFrame
执行速度
这个函数的执行速度很快,但有时候需要减缓执行,可以使用下面的封装
function doNextFrame(callback, gapTimes = 1) {
let last = Date.now(); // 最后一次执行时刻 ms
let now = null; //现在 ms
const interval = (1000 / 60) * gapTimes; // 时间间隔,ms
draw();
function draw() {
requestAnimationFrame(draw);
now = Date.now();
if (now - last >= interval - 1000 / 120) {
last = now;
callback();
}
}
}
# BUG
如果发现 bug 或者其他需求可以联系作者 也十分欢迎 pr 前往 github (opens new window)