Reactour新手导航原理及升级一

1,807 阅读3分钟

1 前言

想必大家都有使用/开发过新手导航的经历——为了让用户熟知产品的用法,往往会增加一个引导,常见的方式就是使用一个黑色的半透明蒙版,然后需要关注的区域是镂空的。新手导航主要如下图所示:

image.png

一个新手引导往往包括三个部分组成:

  1. 内容高亮区域(visible content)
  2. 引导提示区域(guide)
  3. 半透明灰色遮罩(mask) 大部分还会在content区域再加一层透明层,防止用户点击。

guide提示区域比较容易,实现方法都是直接把这一部分设置一个比较大的z-index即可,让这个guide区域的位置随着内容区域的变化而变化。而content和mask区域既可以看成是一个整体,也可以单独的拆开实现。

2 实现蒙层的原始思路

  1. 通过z-index实现
  2. 通过border实现
  3. 通过box-shadow实现
  4. 通过canvas实现 以上四种方法借鉴了这篇《新手导航实现的四种思路》博客,这里不具体展开。
    接下来介绍另外一种,使用svg的mask元素实现的新手导航。

svg的mask原理和PS的蒙版原理相同,如下所示:

45ebb88b-60fe-4176-85a5-33988e136fc9.png 蒙版: 黑色则抠除,白色显示,灰色则半透明

我们利用蒙版抠出一个和需要高亮区域大小相同的内容即可。

  1. 先画一个和浏览器大小一样的rect元素,fill=white (底板)
  2. 把我们需要高亮的区域的fill值设置为black(内容)
  3. 设置和第一步一样大小的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>

bfa0251f-7928-4b20-bad8-622905d7cdb8.png

3 reactour的实现思路

3.1 reactour的demo样式

下面是我实现的一个极简demo,目的是主要看看它的结构,以便和之后我升级之后的结构做对比。 image.png

3.2 实现原理

Reactour的主要原理是使用svg的mask元素,先简要介绍一下Reactour实现抠图效果的结构,在页面上一共盖了三层。如下图所示:

image.png

第一层是mask元素做遮罩,在遮罩中会留和内容宽高相同的黑色区域(参考上文代码遮罩的svg实现),主要是为了露出内容。
第二层是使用clip-path元素实现的裁剪,把除内容之外的区域裁剪出来,盖上一层浅色,目的是为了防止点击到别的地方。
第三层是使用rect透明矩形给内容区域盖上,防止用户点击,不响应任何事件。

3.3 改造的reactour

了解了以上原理之后,接下来就是实现符合自己的UI样式,例如要在内容和提示框之间增加一条线、给内容区域增加2层或3层的border、改变提示框的布局等等。
为了兼容本部门其他同学使用该组件包,最终做出如下改变:

  1. 增加 distance:number 参数,distance 参数指的是提示框和高亮内容的距离
  2. 增加lineType:"dash" || "solid"参数,指distance线条的样式,默认值为"dash"
  3. 增加outlineNum:number参数,指高亮内容被包裹的边框层数,可选2或3,默认为3
    实现的demo样式如下:

image.png

关闭按钮和Next按钮可自由配置,此处没任何样式。

改造后的Reactour代码稍后上传npm,有需要的可以留言,下一期将详细介绍Reactour的具体代码。