1 前言
想必大家都有使用/开发过新手导航的经历——为了让用户熟知产品的用法,往往会增加一个引导,常见的方式就是使用一个黑色的半透明蒙版,然后需要关注的区域是镂空的。新手导航主要如下图所示:
一个新手引导往往包括三个部分组成:
- 内容高亮区域(visible content)
- 引导提示区域(guide)
- 半透明灰色遮罩(mask) 大部分还会在content区域再加一层透明层,防止用户点击。
guide提示区域比较容易,实现方法都是直接把这一部分设置一个比较大的z-index即可,让这个guide区域的位置随着内容区域的变化而变化。而content和mask区域既可以看成是一个整体,也可以单独的拆开实现。
2 实现蒙层的原始思路
- 通过
z-index实现 - 通过
border实现 - 通过
box-shadow实现 - 通过
canvas实现 以上四种方法借鉴了这篇《新手导航实现的四种思路》博客,这里不具体展开。
接下来介绍另外一种,使用svg的mask元素实现的新手导航。
svg的mask原理和PS的蒙版原理相同,如下所示:
蒙版: 黑色则抠除,白色显示,灰色则半透明
我们利用蒙版抠出一个和需要高亮区域大小相同的内容即可。
- 先画一个和浏览器大小一样的
rect元素,fill=white(底板) - 把我们需要高亮的区域的fill值设置为black(内容)
- 设置和第一步一样大小的
rect元素,fill=white(蒙版) 实现代码如下:
<body>
<div>
<div>这是要展现的内容</div>
<button onclick="fn()">点击这里</button>
<svg
style="position: absolute; top: 0; left: 0; width: 500; height: 500;"
>
<defs>
<mask id="mask-main">
<rect x="0" y="0" width="500" height="500" fill="white" />
<rect x="0" y="0" width="200" height="200" fill="black" />
</mask>
</defs>
<rect
x="0"
y="0"
width="500"
height="500"
fill="rgba(0,0,0,0.5)"
mask="url(#mask-main)"
/>
</svg>
</div>
</body>
3 reactour的实现思路
3.1 reactour的demo样式
下面是我实现的一个极简demo,目的是主要看看它的结构,以便和之后我升级之后的结构做对比。
3.2 实现原理
Reactour的主要原理是使用svg的mask元素,先简要介绍一下Reactour实现抠图效果的结构,在页面上一共盖了三层。如下图所示:
第一层是mask元素做遮罩,在遮罩中会留和内容宽高相同的黑色区域(参考上文代码遮罩的svg实现),主要是为了露出内容。
第二层是使用clip-path元素实现的裁剪,把除内容之外的区域裁剪出来,盖上一层浅色,目的是为了防止点击到别的地方。
第三层是使用rect透明矩形给内容区域盖上,防止用户点击,不响应任何事件。
3.3 改造的reactour
了解了以上原理之后,接下来就是实现符合自己的UI样式,例如要在内容和提示框之间增加一条线、给内容区域增加2层或3层的border、改变提示框的布局等等。
为了兼容本部门其他同学使用该组件包,最终做出如下改变:
- 增加
distance:number参数,distance参数指的是提示框和高亮内容的距离 - 增加
lineType:"dash" || "solid"参数,指distance线条的样式,默认值为"dash" - 增加
outlineNum:number参数,指高亮内容被包裹的边框层数,可选2或3,默认为3
实现的demo样式如下:
关闭按钮和Next按钮可自由配置,此处没任何样式。
改造后的Reactour代码稍后上传npm,有需要的可以留言,下一期将详细介绍Reactour的具体代码。