Author: Mountain ant

Guide Mask A guide for new users when a new service is launched or a service is changed. The following page is a mask that highlights what we need to highlight at a local location:

Currently found a lot of pages do mask guide, or use the form of pictures to do.

Image guided masks have several disadvantages:

  1. Large images affect loading
  2. The content of the picture is fake, and the real bottom content does not match
  3. Full screen mask image, the image width height is not consistent with the screen width height, the display side left black, or compression effect.
  4. The lead position of the image cannot be clicked.
  5. Low? Not cool?

This article describes six ways to achieve guidance mask

  • Z-index implements the mask layer
  • Dynamic opacity implementation
  • Border implementation
  • The box – shadow
  • Node replication implementation
  • Canvas implementation

The above six guiding mask implementation ideas can meet the business requirements in certain circumstances and realize the guiding mask from different perspectives. Z-index is the simplest, while Canvas is the most flexible. Personally, I prefer skeleton screen style implementation of dynamic opacity, which is more interesting and cool!!

Idea 1: Use z-index

  • Add a new div and set it to a semi-transparent area that will cover the entire page
  • The semi-transparent mask area z-index is larger than the page element
  • The guide content area is larger than the semi-transparent mask area Z-index

All we need to do is set the guiding content area to the top level, set a mask layer below the guiding content area, and set the mask layer for the other content elements’ Z-index. Let’s look at a simple example.

.z1{
  position:absolute;
  left:50px;
  top:50px;
  width:50px;
  height:50px;
  background:blue;
  z-index:1;
}
.z2{
  position:absolute;
  left:60px;
  top:60px;
  width:50px;
  height:50px;
  background:red;
  z-index:2;
}
.z3{
  position:absolute;
  left:70px;
  top:70px;
  width:50px;
  height:50px;
  background:yellow;
  z-index:3;
}
Copy the code

Let’s change the style of z2.

.z2{
  position:absolute;
  left:50px;
  top:50px;
  width:50px;
  height:50px;
  background:black;
  opacity:0.5;
  z-index:2;
  animation:z_index 2s linear infinite alternate;
}
@keyframes z_index {
    from {
      left:50px;
      top:50px;
      width:50px;
      height:50px;
    }
    to {
      left:0px;
      top:0px;
      width:200px;
      height:200px; }}Copy the code

As long as the elements that need to be masked are determined, and the z-index + opacity of the elements is set dynamically with JS when the page elements are laid out, the guide mask effect of the page can be well achieved.

Idea 2: Use opacity to make non-mask elements translucent

  • The boot content area does not need to be changed
  • The other node elements on the page are translucent

Instead of adding a mask, we completely manipulate the page nodes, making the nodes that need to be masked translucent, and the content that guides the mask is fully displayed. The effect of the page is different from that of the mask. For the white space, we still display it completely, but give the content elements a translucent, skeleton-like effect. To illustrate the effect, let’s look at the following example: Page setup has six elements.

<div class="wrap">
    <div class="z z1"></div>
    <div class="z z2"></div>
    <div class="z z3"></div>
    <div class="z z4"></div>
    <div class="z z5"></div>
    <div class="z z6"></div>
  </div>
Copy the code

Lay out the element content side by side in Flex.

.wrap{
  display:flex;
  flex-wrap:wrap;
  width:150px;
}
.z{
  width:50px;
  height:50px;
  transition:all 1s;
}
.z1{
  background:blue;
}
.z2{
  background:black;
}
.z3{
  background:yellow;
}
.z4{
  background:red;
}
.z5{
  background:green;
}
.z6{
  background:orange;
}
Copy the code

Simulate the mask layer by displaying the current element using the JS operation, which in turn renders the other elements translucent.

let arry = Array.from(document.querySelectorAll(".z"));
let index = - 1;
let direct = 1;
setInterval((a)= >{
  if(index>=5) direct = - 1;
  else if(index<=0) direct = 1;
  index = index+direct;
  arry.forEach((d,i) = >{
    d.style.opacity = 1;
  });
  setTimeout((a)= >{
    arry.forEach((d,i) = >{
      if(i==index) return;
      d.style.opacity = 0.1;
    });
  },1000);
},2000)
Copy the code

Looking at this example, we can clearly see the implementation of the bootstrap mask. This kind of guiding mask is actually more fun, a bit like the current popular skeleton screen, other existing elements that need to be masked content is the gray part of the skeleton screen, the need to show is the key mask content. Interesting!!

Idea 3: Use the border method to achieve

> > < p style = “margin-bottom: 0pt; margin-bottom: 0pt;

div {
    border:1px solid #red;
}
Copy the code

So how do you use border to bootstrap the mask?

1. Understand triangles

Let’s start with a simple example:

<div class="border_1"></div>
Copy the code
.border_1{
    width: 100px;
    height: 100px;
    border-top:50px solid red;
    border-right: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 50px solid transparent;
    box-sizing:border-box;
}
Copy the code

The implementation of an inverted triangle, this application scenario is not more, a lot of tips guidance, annotations and so on will be used. I’ve seen this inverted triangle with a picture instead. Look carefully at this code, there are three main implementations:

  1. We have borders on all four sides
  2. Width and height are 100px, which is the sum of the top, bottom, left and right boxes.
  3. Only the top border is red, the rest of the border is transparent.

To understand the above implementation, let’s look at the following code:

.border_2{
    width: 100px;
    height: 100px;
    background-color:green;
    border-style:solid;
    border-color:red yellow blue black;
    border-width:50px;
    animation:border_ani 2s linear infinite alternate;
    box-sizing:border-box;
}
@keyframes border_ani {
    from {
        border-width:50px;
    }
    to {
      border-width:0; }}Copy the code

From the figure, we can clearly see that the green background of the entire div changes with the change of the border-width.

  • When border-width=0, the whole page only has a green background, that is, the size of the content
  • When border-width=50, the size of the entire div is filled with the border, and the top, bottom and left are divided into 1/4 equally, which is four inverted triangles.

So we can clearly get:

Border-right: transparent; border-left: transparent; border-bottom: transparent; border-top: red;

Similarly, we can also set the size of the border is not consistent, we can achieve the oblique triangle:

.border_3{
    width: 0;
    height: 0;
    border-top:30px solid red;
    border-right: 10px solid transparent;
    border-bottom: 20px solid transparent;
    border-left: 100px solid transparent;
    box-sizing:border-box;
}
Copy the code

You can also achieve the trapezoid that you often encounter in your work:

.border_4{
    width: 150px;
    height: 150px;
    border-top:50px solid red;
    border-right: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 50px solid transparent;
    box-sizing:border-box;
}
Copy the code

Well, this is not cumbersome, interested in all kinds of try. Encounter this kind of simple line diagram, do not use the picture at all times.

2. Look at the implementation guide mask

  • Add a div as the mask element
  • The middle size of the div is exactly the same as the size of the boot content element, and the positions overlap
  • The border of the div is set to translucent and infinitely enlarged

Once you know the implementation of the triangle above, you should be able to figure out how to guide the mask. A div has four borders. If we set the borders to be translucent and the middle area (the top border_2 green) to be completely transparent, wouldn’t we be able to implement the region guide mask? Then set the border to be larger than the size of the screen, which is the panoramic guide mask!

.border_5{
    width: 150px;
    height: 150px;
    border-top:50px solid rgba(0, 0, 5);border-right: 50px solid rgba(0, 0, 5);border-bottom: 50px solid rgba(0, 0, 5);border-left: 50px solid rgba(0, 0, 5);box-sizing:border-box;
}
Copy the code

This is a 150px region mask, which can be seen in the following example:

.border_6{
    width: 20px;
    height: 20px;
    border-style:solid;
    border-color:rgba(0, 0, 5);border-width:20px;
    animation:border_ani 2s linear infinite alternate;
    box-sizing:content-box;
}
@keyframes border_ani {
    from {
        border-width:20px;
    }
    to {
      border-width:100px; }}Copy the code

Of course, we can also set border-RADIUS to achieve the circular mask area, as follows:

Of course, here the border size value is written dead, the specific implementation needs to change or dynamic change according to the page content.

What if it’s an ellipse?

Conclusion:

Border can realize the shape of a variety of edge lines, can realize the guidance of the mask layer, the specified area of the page is transparent, and the other is translucent to achieve.

Four, the use of box-shadow to achieve

  • Add a div as the mask element
  • Div sizes and content elements are exactly the same size and overlap
  • The box-shadow size of the div is set to semi-transparent and a relatively large size of about 2000px

Box-shadow: Box shadow: Box shadow: Box shadow: Box shadow

.boxshadow_1{
    width:50px;
    height:50px;
    background:blue;
    box-shadow: 10px 10px 5px 4px # 000;
}
Copy the code

On the 50px width/height div, its shadow is 10px both horizontally and vertically, the shadow blur distance is 5px, the shadow size is 4px, and the shadow is #000 color (I added a yellow background color for the body to make it easy to distinguish).

First we make the shadow transparent:

.boxshadow_2{
    width:50px;
    height:50px;
    background:blue;
    box-shadow: 10px 10px 5px 4px rgba(0, 0, 5); }Copy the code

So how do you make a shadow cover the whole page?

  • The horizontal and vertical distance of the shadow is the distance from the original dev, this adjustment will not work, it will only make the shadow more away from the element.
  • The blur distance of the shadow is how far the edge of the shadow will blur. The longer the distance, the longer the blur will be. The size of the mask will not change.
  • The size of the shadow, this is the size of the shadow, what if we make the shadow size big? Yes, that’s it

In the following example, we adjust the size of the shadow:

.boxshadow_3 {
  width:50px;
  height:50px;
  background:blue;
  box-shadow: 0px 0px 5px 0px rgba(0, 0, 5);animation:box_ani 2s linear infinite alternate;
}
@keyframes box_ani {
    from {
        box-shadow: 10px 10px 5px 0px rgba(0, 0, 5); }to {
        box-shadow: 10px 10px 5px 100px rgba(0, 0, 5); }}Copy the code

As above, we only need to increase the shadow size to achieve the guiding mask. What if you need to boot the mask and still be able to respond to events? Just add the pointer-events attribute.

Do not blindly set the shadow distance of box-shadow to be too large. After testing, if the value is too large, such as 4000px, the shadow cannot be displayed on some mobile phones. After practice, 2000px is a good setting.

Idea 5: Use page node replication

  • Add two new divs, a translucent mask element, and a mask content area
  • Copies the page node bootstrap content into the Mask content area
  • Make the size and position of the mask content area exactly the same as the original node boot content

The page content is ready, we need a guiding mask to display an element, so copy the element to the outermost layer, add a layer of the top layer of the mask to do that, and highlight the guiding content above the mask.

<div class="content one">I'm the first div. I'm the first div</div>
<div class="content two">I'm the second div. I'm the second div</div>
<div class="content three">I'm the third div. I'm the third div</div>
<div class="content four">I'm the fourth div. I'm the fourth div</div>
<div class="mask"></div>
<div id="maskContent"></div>
Copy the code

Here we have a fixed mask and a fixed mask content element that we just need to fill.

.content{
    padding:10px;
    z-index:0;
}
.mask{
    position:fixed;
    left:0;
    top:0;
    width:100%;
    height:100%;
    background:rgba(0, 0, 8);z-index:900
  }
  #maskContent{
    position:fixed;
    z-index:999;
    display:inline-block;
    background-color: #fff;
  }
Copy the code

So the content area is 0, and then the mask is 900, so our mask element is 999, which is the top layer.

function renderContent(cls){
    let targetNode = document.querySelector(`.${cls}`);
    let maskContent = document.getElementById("maskContent");
    maskContent.innerHTML = targetNode.outerHTML;
    let pos = targetNode.getBoundingClientRect();
    maskContent.style.top=pos.top+"px";
    maskContent.style.left=pos.left+"px";
    maskContent.style.width=pos.width+"px";
    maskContent.style.height=pos.height+"px";
 }
let i = 0;
setInterval((a)= >{
    renderContent(['one'.'two'.'three'.'four'][i]);
    if(++i>=4) i = 0;
},1000)
Copy the code

Here, to demonstrate the effect, a timer is added to change the different masks. Easy to understand, look at the effect:

Idea 6: Use Canvas

  • Add a new canvas and draw the graph twice
  • First: Draw a full screen translucent shadow
  • Second: Use XOR to draw an area that perfectly coincides with the size and position of the bootstrap content area

The second time the content area is drawn is overlapped with the first one, using XOR, so it is transparent, and the boot content area will be fully displayed, which is what we want.

Using canvas globalCompositeOperation attributes, content reference http://www.tutorialspoint.com/html5/canvas_composition.htm

Shapes are made transparent where both overlap and drawn normal everywhere else. The shape drawn on the Canvas will be transparent on the overlap, and will be drawn on the non-overlap.

So we can draw a canvas mask in the canvas, and then use XOR to draw the overlapped content in the mask, and then the overlapped content will be transparent, so the content in this transparent area is the content we want to guide the mask to highlight the content area. Examples:

 <div class="content one">I'm the first div. I'm the first div</div>
<div class="content two">I'm the second div. I'm the second div</div>
<div class="content three">I'm the third div. I'm the third div</div>
<div class="conteent four">I'm the fourth div. I'm the fourth div</div>
<canvas id="mask"></canvas>
Copy the code

Add a Canvas node to the page. Set the canvas as a whole to translucent, and then use XOR to draw the content.

 function mask(cls){
    let targetNode = document.querySelector(`.${cls}`);
    let pos = targetNode.getBoundingClientRect();
    let canvas = document.getElementById("mask");
    let width = window.innerWidth;
    let height = window.innerHeight;;
    canvas.setAttribute("width", width);
    canvas.setAttribute("height",height);
    var ctx = canvas.getContext("2d"); 
    ctx.globalCompositeOperation = 'source-over';
    ctx.fillStyle ='rgba (255, 255, 255, 0.9)';
    ctx.fillRect(0.0, width, height);
    ctx.fill();
    ctx.fillStyle ='white';
    ctx.globalCompositeOperation="xor";
    ctx.fillRect(pos.left,pos.top,pos.width,pos.height);
    ctx.fill();
 }
let array = ['one'.'two'.'three'.'four'];
let i = 0;
setInterval((a)= >{
    mask(array[i]);
    i++;
    if(i>=4) i = 0;
},1000)
Copy the code

After looking at the above implementations, which one do you like best?


If you think this post is valuable to you, please like it and follow us on our website and our WecTeam account, where we will post quality articles every week: