前言
引导动画是程序在某一时刻播放的动画,通常用于向用户介绍程序的功能和特点。
实现效果
实现方式
引导动画的实现方式有很多种,这里我使用的是 CSS 的 clip-path
属性。
技术选型
这里我为什么要选择 clip-path
属性而不是 mask
属性呢?因为我试了下 mask
好像只能在上层加个半透明背景,虽然它可以通过 CSS 的渐变实现绘制出某个元素的位置上方的背景为透明色,但是这个背景仍然是全屏覆盖的,还是会遮挡下方元素的点击等操作。
后来我试了下将下方被遮挡的元素完全复制到背景上方,这样就能实现元素不被遮挡的效果了,但是点击等事件并不能复制过来,所以最后我选择了 clip-path
属性。
从背景中抠出一块矩形区域的 CSS 代码如下:
mask: {
display: none,
transition: all 1s,
width: 100vw,
height: 100vh,
background: rgba(0, 0, 0, 0.5),
position: absolute,
top: 0,
left: 0,
clipPath: polygon(0% 0%, 0% 100%, 200px /* x坐标的最小值 */ 100%,
200px 100px, /* 左上角坐标 */
400px 100px, /* 右上角坐标 */
400px 200px, /* 右下角坐标 */
200px 200px, /* 左下角坐标 */
200px /* x坐标的最小值 */ 100%, 100% 100%, 100% 0%),
}
实现步骤
- js 创建创建背景层和提示文字层,并赋予样式
- js 动态计算每一步骤的坐标,并更新背景层的样式
- js 监听每一步骤的点击事件,并更新背景层的样式
- js 监听每一步骤的动画结束事件,并更新背景层的样式,跳转到下一步骤,并播放下一步骤的动画,最后隐藏背景层及提示文字层
技术难点
因为 img 元素是异步加载的,所以需要异步等待 img 元素加载完成后再进行计算,所以我将 img 的 onload 事件封装成了异步函数,并使用 await 来同步操作,但这样的话在外层也需要使用 await 来进行等待。所以我使用了执行器队列来解决这一问题。即在外部调用某个函数时将该函数放入队列中,最后使用循环来依次按先后顺序执行队列中的函数。
安装及使用
npm i guide-anime
这样在使用时就可以直接这样写:
const guider = Guide();
guider.setOptions({
steps: [
{
element: "#vite",
},
{
element: "#vue",
},
],
});
guider.start();
总结
我已经将这个库封装成一个 npm 包,并添加更多的功能,比如自动计算每一步骤的坐标,以及自动播放每一步骤的动画等。
具体使用请参考 guide-anime
此项目的开发让我对前端有了更深的理解,我将继续钻研前端工程化方面的知识。
参考
- 使用 CSS 渐变
- 奇妙的 CSS MASK
- clip-path
- clip-path 在线生成器