Ant Design Logo彩蛋动画实现
前言
我们在做Web网页端项目的时候常常希望能让一些部件看起来更加美观,毕竟 “爱美之心,人皆有之”。然而,自己一个一个写 CSS
和 JS
实现又很麻烦。因此,现在出现了很多 UI 库,如 Ant Design、Element UI 等。这些库封装好了各式各样的网页部件,如 Button
、Icon
、Menu
等,十分美观,我们可以直接拿来用。
有一天,打开 Ant Design 官网时,发现主页的 Logo 存在一个 隐藏彩蛋 👉 当我们把鼠标移入 Ant Design Logo上时,字母 i
上的图标会动态变化。
So,I have a dream ! …扯远了,So 我打算自己重现彩蛋动画。
实现原理
首先,我们实现的方法有两种:
- 基于
JavaScript
脚本 - 基于
CSS
动画
这里我们选择使用 基于 CSS
动画 实现该效果。
为什么不使用
JavaScript
脚本呢? 因为JavaScript
实现动画的原理在于为元素绑定事件函数,实现多种动画样式,显然这种方式可以实现复杂动画且自由度高。然而也存在一些缺点,如 代码量庞大,以及Js动画执行时是在主线程中运行,主线程中同时可能还有其他的Js脚本,可能会导致线程出现阻塞,加载慢,出现丢帧的情况。
基于 CSS
动画实现的思路为:将小图标在水平方向上拼接成长图,设置播放窗口大小为一个小图标的大小,并利用 cover
方式设置图片大小,以实现窗口只显示一个小图标,通过让小图标拼接图像左/右移动,实现图标切换播放。
具体流程如下:
- 准备好 Ant Design的 Logo 图标和各式各样的小图标拼接图。
- 以Logo图标作为底,利用 层叠样式的伪类元素
::after
配合CSS animation
实现小图标播放。 - 通过鼠标
hover
来控制动画的开始与暂停。
准备工作
我们需要准备两个图片素材,分别是 Ant Design Logo 图标 和 Icons 拼接图。
感谢:这里直接引用iCSS前端趣闻公众号XboxYan博主的素材。
Ant Design Logo 图标
将 Ant Design Logo中字母 i
的一点扣掉,如下:
Icons 拼接图
为了避免多次请求,也为了方便创建动画,这里把所有小图标素材组合在一块(从官网另存下来的),如下:
开始实现
实现流程主要分为两个步骤: CSS
动画设置 和 动画播放与暂停。
CSS 动画设置
首先,我们要在 <style>
标签中先定义 .logo
样式,将 Ant Design Logo作为我们的底图。
然后, 可变化的小图标用伪元素 ::after
生成(装饰性的元素都可以用伪元素来生成,保证HTML的整洁),代码如下:
1 | <style> |
上述代码,在伪类
::after
中,我们要定义窗口大小为height: 32px; width: 32px;
以及设置图片大小为background-size: cover;
从而只显示一个图标。接着利用
right:113px; top: -18px;
将窗口对应到字母i
的上方。如果不了解
background
的相关参数的话,可以参考本人 Github 中的 CSS 笔记 👉 设置背景图片。
静态效果如下:
我们刚刚在 思路 中提到,动画实现效果就是 让条状长图在一个窗口上向左/右移动。那么我们需要自定义一个 move
动画实现 background-position
的改变:
1 | /* 动画函数 -- background-position 在水平位置上移动到100% */ |
接着,我们在伪类 ::after
中定义动画即可。如下所示:
1 | .logo::after{ |
上述代码中,最重要的就是
steps(num, position)
逐帧播放函数,如有不了解,请移步 👉 CSS动画steps功能,当然也推荐你去查阅官方文档。如果不了解
animation
的相关参数的话,可以参考本人 Github 中的 CSS 笔记 👉 animation动画。
至此,我们的彩蛋复现已经完成了一大半了,效果如下:
动画播放与暂停
从上面的动画效果可以看到,我们已经实现了图标的动态变换功能了。然而,距离完成还差一步:通过鼠标的 hover
控制动画的播放与暂停。
因此,我们需要在给 .logo
样式的伪类 ::after
添上 hover
属性。简单来说,思路就是:没有hover就不播放动画,hover了之后添加并播放动画。代码如下:
1 | <style> |
效果如下:
然而,虽然实现了 hover
控制播放的开始与暂停,但是我们发现:当我们鼠标移开始之后,小图标又回到了点阵图。即每次都是重新创建动画,都是从头开始。这不仅不满足我们的需求,而且多次创建动画还会影响渲染的性能。
那我们该如何实现动画的暂停和继续,而不是每次重新开始呢?
我们可以在伪类 after
中创建动画,并通过设置动画的状态 animation-play-state
来控制动画的暂停与开始。代码如下:
1 | <style> |
至此,就完成了我们所有的需求,结果如下:
完整代码为:
1 | <style> |
1 | <div class="logo"></div> |
很感谢你能看到这里!谢谢~
参考资料: (衷心感谢参考资料中各博主的帮助)