注册

😈当一个摆子前端太闲的时候会做什么


国破山河在,城春草木深。 ——杜甫·春望



今日周一,在下与诸位同道中人一起来讨论一个话题:当一个前端空闲的时候会做些什么


🤯是独自深耕论坛,钻研学术?


👯还是三两闲聊打趣,坐而论道?


💆‍♂️亦或是闭目养神,神游天地?




作为一名优秀的(摆子、摸鱼、切图...)前端开发者,在下在空闲时间最喜欢做的还是钻研(混)前端技术(工作量)。


新的一周,新的开始,上篇文章中有同学批评在下说不够“玩”,那么这周就“简单”画一个鼠标精灵再交予各位“玩一玩”吧。



说明一下:在下说的玩,是写一遍嗷


温馨提示:文章较长,图片较多,不耐看的同学可以先去文末玩一玩在下的“大眼”,不满足了再去创造属于各位自己的鼠标精灵



以下是这周“玩具”的简单介绍:



  • 名称:大眼
  • 生辰:发文时间的昨天(2022-08-15)
  • 性别:随意
  • 情绪:发怒/常态
  • 状态:休眠/工作中
  • 简介:没啥特别的,大眼就干一件事,就是盯着你的鼠标,以防你找不到鼠标了。不过大眼有起床气,而且非常懒散,容易犯困。

大眼生活照:


image.png


接下来请各位跟随在下的节奏,一步一步把自己的“大眼”创造出来。


👀 画“大眼”先画圆


老话说“画人先画骨”,同样画大眼也得先画它的骨,嗯......也就是个圆,没错,就是个普通的圆


在下的笔法还是老套路,先给他一个容器。


<div class="eyeSocket"></div>

给大眼容器添加一些必要的样式


body {
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #111;
}
.eyeSocket {
position: absolute; // 浮动居中
left: calc(50% - 75px);
top: calc(50% - 75px);
width: 150px; // 固定宽度
aspect-ratio: 1; // 长宽比 1:1 如果浏览器不支持该属性,换成 height: 150px 也一样
border-radius: 50%;
border: 4px solid rgb(41, 104, 217);
z-index: 1;
}

效果:


image.png


然后就是另外两个圆和一些阴影效果,由于另外两个圆没有特殊的动效,所以在下使用两个伪元素来实现


.eyeSocket::before,
.eyeSocket::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); // 居中
border-radius: 50%;
box-sizing: border-box; // css3盒子模型
}
.eyeSocket::before {
width: calc(100% + 20px);
height: calc(100% + 20px);
border: 6px solid #02ffff;
}
.eyeSocket::after {
width: 100%;
height: 100%;
border: 4px solid rgb(35, 22, 140);
box-shadow: inset 0px 0px 30px rgb(35, 22, 140);
}

效果:


image.png


👀 画龙需点睛


大眼的眼球画好了,之后就需要给它点上眼睛,喜欢什么样的眼睛因人而异,在下就选择这种分割线来作为大眼的眼仁。


为了方便做一些过渡效果,在下使用echarts来完成这个眼仁。


首先在下需要各位通过任何方式引入echarts库,然后给眼仁一个容器,并初始化echarts画布。


<div class="eyeSocket">
<div id="eyeball"></div>
</div>

#eyeball {
width: 100%;
height: 100%;
}

// 画眼球
let eyeball = document.getElementById('eyeball'); // 获取eyeball元素
let eyeballChart = echarts.init(eyeball); // 初始化画布
function getEyeballChart() {
eyeballChart.setOption({
series: [
{
type: 'gauge', // 使用仪表盘类型
radius: '-20%', // 采用负数是为了让分割线从内向外延伸
clockwise: false,
startAngle: '0', // 起始角度
endAngle: '270', // 结束角度
splitNumber: 3, // 分割数量,会将270度分割为3份,所以有四根线
detail: false,
axisLine: {
show: false,
},
axisTick: false,
splitLine: {
show: true,
length: 12, // 分割线长度
lineStyle: {
shadowBlur: 20, // 阴影渐变
shadowColor: 'rgb(0, 238, 255)', // 阴影颜色
shadowOffsetY: '0',
color: 'rgb(0, 238, 255)', // 分割线颜色
width: 4, // 分割线宽度
}
},
axisLabel: false
},
{
type: 'gauge',
radius: '-20%',
clockwise: false,
startAngle: '45', // 倾斜45度
endAngle: '315',
splitNumber: 3,
detail: false,
axisLine: {
show: false,
},
axisTick: false,
splitLine: {
show: true,
length: 12,
lineStyle: {
shadowBlur: 20,
shadowColor: 'rgb(0, 238, 255)',
shadowOffsetY: '0',
color: 'rgb(0, 238, 255)',
width: 4,
}
},
axisLabel: false
}
]
})
}
getEyeballChart();

效果:


image.png


眼仁就这么轻轻松松的画好了,对于常用echarts的同学可以说是轻而易举,对吧。


同时一个静态的大眼也创建完毕,接下来就要给大眼赋予生命了。



再次提醒:长文,而且代码量多,建议抽思路看即可。



✨ 生命仪式:休眠状态


赋予生命是神圣的,她需要一个过程,所以在下从最简单的开始——休眠状态


在下给大眼设计的休眠状态,就是闭着眼睛睡觉,其实不露出眼仁同时有节奏的呼吸(缩放)罢了,相比于整个生命仪式来说,还是比较简单的,只需要修改大眼外框的大小即可。


呼吸

这里在下采用的是css转换+动画的方式


<div class="eyeSocket eyeSocketSleeping">
<div id="eyeball"></div>
</div>

/* ...其他样式 */
.eyeSocketSleeping {
animation: sleeping 6s infinite;
}

@keyframes sleeping {
0% {
transform: scale(1);
}

50% {
transform: scale(1.2);
}

100% {
transform: scale(1);
}
}

sleeping.gif


闭眼

搞定了呼吸,但是睁着眼睛怎么睡得着?


所以接下来在下要帮助大眼把眼睛闭上,这时候咱们前面给眼睛设置负数radius的好处就来了(其实是在下设计好的),因为分割线是从内向外延伸的,所以此时只需要慢慢减小分割线的高度,即可实现眼睛慢慢缩小的效果,即在下给大眼设计的闭眼效果。


实现的效果是:大眼慢慢闭上眼睛(分割线缩小至0),然后开始呼吸


直接上代码


<div class="eyeSocket" id='bigEye'> // 去掉 eyeSocketSleeping 样式,添加id
<div id="eyeball"></div>
</div>

let bigEye = document.getElementById('bigEye'); // 获取元素
// ...其他代码
let leftRotSize = 0; // 旋转角度
let ballSize = 12; // 眼睛尺寸
let rotTimer; // 定时器

function getEyeballChart() {
eyeballChart.setOption({
series: [
{
startAngle: `${0 + leftRotSize * 5}`, // 加为逆时针旋转,乘5表示速度为leftRotSize的倍
endAngle: `${270 + leftRotSize * 5}`, // 即变为每10微秒移动0.5度,1234678同理
// ...其他
splitLine: {
length: ballSize, // 分割线高度设置为眼球尺寸变量
},
},
{
startAngle: `${45 + leftRotSize * 5}`,
endAngle: `${315 + leftRotSize * 5}`,
// ...其他
splitLine: {
length: ballSize, // 同上
}
},
}
]
})
}
// 休眠
function toSleep() {
clearInterval(rotTimer); // 清除定时器
rotTimer = setInterval(() => {
getEyeballChart()
if (ballSize > 0) {
ballSize -= 0.1; // 当眼球存在时慢慢减小
} else {
bigEye.className = 'eyeSocket eyeSocketSleeping'; // 眼球消失后添加呼吸
}
leftRotSize === 360 ? (leftRotSize = 0) : (leftRotSize += 0.1); // 旋转,
}, 10);
}
getEyeballChart();
toSleep()


旋转实现原理:(看过在下第一篇动效的同学对旋转的实现原理应该不陌生)


修改每个圈的起始角度(startAngle)和结束角度(endAngle),并不断刷新视图,


增加度数为逆时针旋转,减去度数为顺时针旋转



如此一来就实现了眼睛缩小消失,然后开始呼吸的过程,同时咱们的大眼也进入了生命仪式之休眠状态(乱入的鼠标有点烦);


tosleep.gif


✨ 生命仪式:起床气状态


在下相信,在座(站?蹲?)的各位同僚身边或者自身都存在一些小毛病,譬如咱们的大眼,它不但懒,喜欢睡觉,甚至叫醒它还会生气,通俗讲就是有起床气


心理学上说有种说法是:情绪会让你接近生命的本真


生命不就是情绪的结合嘛,没有情绪怎么能称之为生命的呢?


在设计之前我们还有点准备工作,就是让大眼先处于休眠状态


<div class="eyeSocket eyeSocketSleeping" id='bigEye'> // 添加休眠
<div id="eyeball"></div>
</div>

// ...其他代码
let ballSize = 0; // 初始眼球尺寸为0
// ...其他代码
// getEyeballChart(); // 把这两行删掉
// toSleep() // 把这两行删掉

唤醒

然后我们需要唤醒大眼,所以首先我们需要添加唤醒动作——点击事件;


let bigEye = document.getElementById('bigEye'); // 获取元素
// ...其他代码
let leftRotSize = 0;
let ballSize = 0;
let rotTimer;
let isSleep = true; // 是否处于休眠状态
// 添加点击事件,当处于休眠状态时执行唤醒方法
bigEye.addEventListener('click', () => {
if (!isSleep) return;
clickToWeakup();
})
// 唤醒
function clickToWeakup() {
isSleep = false; // 修改状态
bigEye.className = 'eyeSocket'; // 清除休眠状态
clearInterval(rotTimer); // 清除定时器
rotTimer = setInterval(() => {
getEyeballChart()
ballSize <= 12 && (ballSize += 0.1);
leftRotSize === 360 ? (leftRotSize = 0) : (leftRotSize += 0.1);
}, 10);
}

这样点一下大眼它就苏醒了过来:


toWeakup.gif


生气

但是!


这是一个没有情绪的大眼,而在下需要的是一个有起床气的大眼,所以这样的大眼咱们不要!


退格←...退格←...退格←...退格←...退格←...退格←......


......


慢点慢点,也不是全都不要了,咱们只需要修改一下他唤醒以后的操作,给他添加上起床气不就行了?


接着来吧:


首先我们把代表了大眼常态的蓝色系抽离出来,使用css变量代替,然后再苏醒后给他添加成代表生气的红色系


body {
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #111;
perspective: 1000px;
--c-eyeSocket: rgb(41, 104, 217);
--c-eyeSocket-outer: #02ffff;
--c-eyeSocket-outer-shadow: transparent;
--c-eyeSocket-inner: rgb(35, 22, 140);
}
.eyeSocket {
/* 其他属性 */
border: 4px solid var(--c-eyeSocket);
box-shadow: 0px 0px 50px var(--c-eyeSocket-outer-shadow); /* 当生气时添加红色外发光,常态则保持透明 */
transition: border 0.5s ease-in-out, box-shadow 0.5s ease-in-out; /* 添加过渡效果 */
}
.eyeSocket::before,
.eyeSocket::after {
/* 其他属性 */
transition: all 0.5s ease-in-out; /* 添加过渡效果 */
}
.eyeSocket::before {
/* 其他属性 */
border: 6px solid var(--c-eyeSocket-outer);
}
.eyeSocket::after {
/* 其他属性 */
border: 4px solid var(--c-eyeSocket-inner);
box-shadow: inset 0px 0px 30px var(--c-eyeSocket-inner);
}

// ...其他代码
let ballColor = 'transparent'; // 默认透明,其实默认是啥都无所谓,反正看不见

function getEyeballChart() {
eyeballChart.setOption({
series: [
{
// ...其他
splitLine: {
// ...其他
lineStyle: {
// ...其他
shadowColor: ballColor, // 把眼睛的眼影颜色设为变量控制
color: ballColor,
}
},
},
{
// ...其他
splitLine: {
// ...其他
lineStyle: {
// ...其他
shadowColor: ballColor,
color: ballColor,
}
}
},
}
]
})
}
// 生气模式
function setAngry() {
// 通过js修改body的css变量
document.body.style.setProperty('--c-eyeSocket', 'rgb(255,187,255)');
document.body.style.setProperty('--c-eyeSocket-outer', 'rgb(238,85,135)');
document.body.style.setProperty('--c-eyeSocket-outer-shadow', 'rgb(255, 60, 86)');
document.body.style.setProperty('--c-eyeSocket-inner', 'rgb(208,14,74)');
ballColor = 'rgb(208,14,74)';
}
// 常态模式
function setNormal() {
document.body.style.setProperty('--c-eyeSocket', 'rgb(41, 104, 217)');
document.body.style.setProperty('--c-eyeSocket-outer', '#02ffff');
document.body.style.setProperty('--c-eyeSocket-outer-shadow', 'transparent');
document.body.style.setProperty('--c-eyeSocket-inner', 'rgb(35, 22, 140)');
ballColor = 'rgb(0,238,255)';
}
// 唤醒
function clickToWeakup() {
isSleep = false;
bigEye.className = 'eyeSocket';
setAngry(); // 设置为生气模式
clearInterval(rotTimer);
rotTimer = setInterval(() => {
getEyeballChart()
ballSize <= 50 && (ballSize += 1);
leftRotSize === 360 ? (leftRotSize = 0) : (leftRotSize += 0.5);
}, 10);
}
// 点击
bigEye.addEventListener('click', () => {
if (!isSleep) return;
clickToWeakup();
})

大眼生气长这样:


angry.gif


更生气

不知道在座(站?蹲擦?)各位是如何看待,但是在下看来,大眼这样好像还不够生气。


没错还不够生气,如何让大眼起来更生气呢,生气到发火如何?


嗦干酒干!


在下这里采用的是svg滤镜的方法,svg滤镜的属性和使用方法非常繁多,在下使用得也不是很娴熟,本文中在下就不赘述了,网上冲浪有许多技术大牛讲的非常好,希望各位勉励自己。emmmm......然后来教会在下,记得给在下留言文章地址


在下使用的是feTurbulence来形成噪声,然后用feDisplacementMap替换来给大眼添加粒子效果,因为feDisplacementMap会混合掉元素,所以在下需要给大眼新增一个大眼替身来代替大眼被融合。


创建大眼替身


<div class="filter"> // 添加滤镜的元素
<div class="eyeSocket" id='eyeFilter'> // 大眼替身
</div>
</div>

.filter {
width: 100%;
height: 100%;
}
.eyeSocket,
.filter .eyeSocket { /* 给替身加上相同的样式 */
/* ...原属性 */
}

image.png


融合


<div class="filter">
<div class="eyeSocket" id='eyeFilter'>
</div>
</div>
<!-- Svg滤镜 -->
<svg width="0">
<filter id='filter'>
<feTurbulence baseFrequency="1">
<animate id="animate1" attributeName="baseFrequency" dur="1s" from="0.5" to="0.55" begin="0s;animate1.end">
</animate>
<animate id="animate2" attributeName="baseFrequency" dur="1s" from="0.55" to="0.5" begin="animate2.end">
</animate>
</feTurbulence>
<feDisplacementMap in="SourceGraphic" scale="50" xChannelSelector="R" yChannelSelector="B" />
</filter>
</svg>

.filter {
width: 100%;
height: 100%;
filter: url('#filter'); /* 开启滤镜 */
}

copy.gif


芜湖~果然献祭了一只“大眼”出来的效果看起来确实还不错哈?确实看起来酷炫多了,不愧是**“献祭”**啊!


真眼出现


既然粒子效果已经产生,咱们的真实大眼也就不需要躲躲藏藏了,该站出来获取这粒子“光环”了!


大眼:哈!


fire.gif


额......


其实......


也挺好看的嘛,不是吗?毕竟不是献祭的真正的大眼,毕竟是个替身,效果没有本体好也是很正常的对吧。



本质上是因为feDisplacementMap设置了scale属性的原因。


feDisplacementMap其实就是一个位置替换滤镜,通过就是改变元素和图形的像素位置的进行重新映射,然后替换一个新的位置,形成一个新的图形。


scale就是替换公式计算后偏移值相乘的比例,影响着图形的偏移量和呈现的效果。



但是话虽如此,咱这个光环不能真的就这么戴着呀,咱们还需要对光环的位置进行一些微调。


.filter .eyeSocket {
left: calc(50% - 92px);
top: calc(50% - 92px);
}

goodfire.gif


看看,看看!这不就顺眼多了吗,献祭了替身,所以尺寸都是非常契合的,而且共用了样式,所以当大眼生气的时候,光环也会跟着生气。


这下光环也有了,看起来的确比之前更生气了。


但是我们还需要对大眼做一些细微的调整,因为大眼在常规状态下并不需要这个光环,睡着的时候光环在旁边“滋啦滋啦”不吵的慌么,所以我们还需要把常态下的大眼光环给消除掉。


在下采用的是不透明度opacity来控制,当大眼处于生气状态时,光环为不透明;处于常规状态时光环透明不可见。


.filter .eyeSocket {
opacity: 0; // 默认状态下不透明度为0
left: calc(50% - 92px);
top: calc(50% - 92px);
transition: all 0.5s ease-in-out; // 添加过渡效果,值得注意的是不能丢了原本的过渡效果,所以这里使用all
}

// ...其他代码
let eyeFilter = document.getElementById('eyeFilter'); // 获取元素
// 唤醒
function clickToWeakup() {
eyeFilter.style.opacity = '1'; // 不透明度设为1
// ...其他
}
deathEye.addEventListener('click', () => {
if (!isSleep) return;
clickToWeakup();
})

这样设置完,一个更生气的大眼就这样出现了:


moreAngry.gif


更更生气


不知看到这样发火的大眼,各位是不是已经满足于此。


但是在下认为不,在下觉得一个真正足够生气的大眼,不只局限于自己生气,还需要找人发泄!!


所以在下还给大眼添加了一些大眼找人的动效(当然是找不到的,它这么笨)。


其实就是让大眼左右旋转,通过css转换来实现。


<div class="eyeSocket eyeSocketSleeping" id='bigEye'>
<div id="eyeball"></div>
</div>
<div class="filter">
<div class="eyeSocket" id='eyeFilter'>
</div>
</div>
<!-- Svg滤镜 -->
<svg width="0">
...
</svg>

/* ...其他样式 */
body {
/* ...其他属性 */
perspective: 1000px;
}
.eyeSocketLooking {
animation: lookAround 2.5s; // 添加动画,只播放一次
}
/* 环视动画 */
@keyframes lookAround {
0% {
transform: translateX(0) rotateY(0);
}

10% {
transform: translateX(0) rotateY(0);
}

40% {
transform: translateX(-70px) rotateY(-30deg);
}

80% {
transform: translateX(70px) rotateY(30deg);
}

100% {
transform: translateX(0) rotateY(0);
}
}

// ...其他代码
let bigEye = document.getElementById('bigEye'); // 获取元素
let eyeFilter = document.getElementById('eyeFilter');

// 唤醒
function clickToWeakup() {
// ...其他代码
eyeFilter.className = bigEye.className = 'eyeSocket eyeSocketLooking'; // 同时给大眼和光环添加环视动画
}

bigEye.addEventListener('click', () => {
if (!isSleep) return;
clickToWeakup();
})

看看大眼在找什么?


lookaround.gif



向左看时,Y轴偏移量为-70px,同时按Y轴旋转-30°


向右看时,Y轴偏移量为70px,同时Y轴旋转30°



✨ 生命仪式:自我调整状态


这个状态非常好理解,大眼虽然有起床气,但是也仅限于起床对吧,总不能一直让它生气,气坏了咋办,带着情绪工作,效果也不好不是吗。


所以我们还需要给它一点时间,让它自我调整一下,恢复成正常状态。


这个自我调整状态就是一个从生气状态变回常态的过程,在这个过程中,大眼需要将生气状态的红色系切换为常态的蓝色系,同时红眼也会慢慢褪去恢复正常。


其实这个自我调整状态还是属于唤醒状态中,只是需要放在起床气状态之后。


这里在下采纳了上文中有位同学给的建议,监听动画结束事件webkitAnimationEnd,然后将自我调整放在动画结束以后。


同时这里也有两个步骤:



  1. 退出起床气状态
  2. 变回常态

为了保证两个步骤的先后顺序,可以使用Promise来实现。不懂Promise的同学可以先去学习一下,在下也讲不清楚哈哈哈哈。


// ...其他代码
bigEye.addEventListener('webkitAnimationEnd', () => { // 监听动画结束事件
new Promise(res => {
clearInterval(rotTimer); // 清除定时器
rotTimer = setInterval(() => {
getEyeballChart(); // 更新视图
ballSize > 0 && (ballSize -= 0.5); // 眼球尺寸减小
leftRotSize === 360 ? (leftRotSize = 0) : (leftRotSize += 0.1);
if (ballSize === 0) { // 当眼球尺寸为0时,将Promise标记为resolved,然后执行后面的代码
clearInterval(rotTimer);
res();
}
}, 10);
}).then(() => {
eyeFilter.style.opacity = '0'; // 清除光环
eyeFilter.className = bigEye.className = 'eyeSocket'; // 清除环视动画
setNormal(); // 设置常态样式
rotTimer = setInterval(() => {
getEyeballChart();
ballSize <= 12 && (ballSize += 0.1); // 眼球尺寸缓慢增加
leftRotSize === 360 ? (leftRotSize = 0) : (leftRotSize += 0.1);
}, 10);
})
})

添加了这样一个监听事件后,咱们的大眼就已经具备了自我调整的能力了:


back.gif


✨ 生命仪式:工作状态


接下来就到了大眼重中之重的环节,也就是大眼的工作状态


在下给大眼的工作非常简单,就是单纯的盯住在下的鼠标,如果各位想给各自的大眼一些其他的功能,可以自己发挥。


盯住鼠标,不只是说说而已,那么怎么样才能让大眼表现出他已经盯住了呢?


在下的思路是:



  1. 以大眼的位置为原点建立一个直角坐标系
  2. 然后通过监听鼠标移动事件,获取鼠标所在位置,计算出鼠标处于大眼坐标系的坐标。
  3. 将整个视口背景以X轴和Y轴进行等分成无数个旋转角度,通过鼠标坐标的数值和正负来调整大眼眼框和眼睛的Y轴和Z轴旋转,从而达到盯住鼠标的目的。

好的,咱们理清思路,接下来就是付诸于行动。


// ...其他代码
// 工作
function focusOnMouse(e) {
{
// 视口尺寸,获取到整个视口的大小
let clientWidth = document.body.clientWidth;
let clientHeight = document.body.clientHeight;
// 原点,即bigEye中心位置,页面中心
let origin = [clientWidth / 2, clientHeight / 2];
// 鼠标坐标
let mouseCoords = [e.clientX - origin[0], origin[1] - e.clientY];
// 旋转角度
let eyeXDeg = mouseCoords[1] / clientHeight * 80; // 这里的80代表的是最上下边缘大眼X轴旋转角度
let eyeYDeg = mouseCoords[0] / clientWidth * 60;
bigEye.style.transform = `rotateY(${eyeYDeg}deg) rotateX(${eyeXDeg}deg)`;
eyeball.style.transform = `translate(${eyeYDeg / 1.5}px, ${-eyeXDeg / 1.5}px)`;
}
}


注意: 如果觉得旋转角度不够大,可以调整代码中的8060,最大可以到180,也就是完全朝向,但是由于大眼终归是一个平面生物,如果旋转度数过大,就很容易穿帮,如果旋转角度为180,大眼就会在某个方向完全消失看不见(因为大眼没有厚度,这个也许是可以优化的点),所以个人喜好调整吧。



咱们来看看大眼工作时的飒爽英姿:


watching.gif


✨ 生命仪式:懒惰状态


顾名思义,懒惰状态就是......懒惰状态。


在下给大眼设计的懒惰状态就是当在下的鼠标超过30秒没有移动时,大眼就会进入休眠状态


所以生命仪式的最后收尾其实非常的轻松,没有大量的代码,只需要添加一个定时器,然后修改休眠状态的代码,将大眼的所有参数初始化即可。


// ...其他代码
let sleepTimer; // 休眠定时器

// 休眠
function toSleep() {
// ...其他操作
document.body.removeEventListener('mousemove', focusOnMouse); // 移除鼠标移动事件
bigEye.style.transform = `rotateY(0deg) rotateX(0deg)`; // 大眼归位
eyeball.style.transform = `translate(0px, 0px)`; // 眼睛归位
}
// 工作
function focusOnMouse(e) {
// ...其他操作
// 设置休眠
if (sleepTimer) clearTimeout(sleepTimer); // 如果休眠定时器已经被设置,则清除休眠定时器
sleepTimer = setTimeout(() => { // 重新计时
toSleep();
}, 30000);
}

感谢上次掘金官方的提醒,在下把线上代码贴在这,在下文笔较差,看不下去的同学可以直接过来玩一玩,感兴趣再去创建自己的大眼。(没有点运行的不要来问我为什么出不来!!!)



如果自己在码上掘金动手的同学记得不要忘记添加echarts资源


image.png


💐 结语


好家伙,原来再写一遍大眼会这么累,这次是真真正正的“玩”了一天,有功夫的各位同僚也可以去玩一玩,于在下的基础上进行完善,创造出属于各位自己的大眼。当然如果有一些比较好玩的动效也可以留言告知在下,当下次混工作量时在下可以有东西写。


就这样!


image.png


作者:Urias
来源:juejin.cn/post/7132409301380890660

0 个评论

要回复文章请先登录注册