preface

A while ago, I was busy looking for a job. During the interview, I encountered an interesting question, so I tried to list as many ways as possible to realize novice guidance animation. Yesterday, I summarized a little and realized 4 ways. Source code at the end, if you want to see the results directly, you can pull to the end to see.

It is assumed that all pop-up layers are based on existing elements on the page

Implement a copy of the target content

Specific steps:

  1. withgetBoundingClientRectGets the display location of the target content
  2. Copy the target content and set the relative location, which was obtained in the previous step, and set the Z-index slightly higher
  3. Add a translucent mask layer beneath the copied content.

Core code:

let target = document.querySelector('.mid-center')
let pos = target.getBoundingClientRect()

let clone = target.cloneNode(true)

clone.style.position = 'fixed'
clone.style.left = pos.left
clone.style.top = pos.top
clone.style.width = pos.width
clone.style.height = pos.height
clone.style.zIndex = 100

document.body.appendChild(clone)
Copy the code

Advantages and disadvantages of ordinary implementation, ordinary, no features.

Implementation two uses box-shadow

Specific steps:

  1. Set the target object’s box-shadow to a large, translucent value
  2. Set the position of the target object to relative

Core code:

let target = document.querySelector('.mid-center')
target.style.boxShadow = 000 4000px RGBA (0, 0, 0, 0.85)
target.style.position = 'relative'
Copy the code

Position :relative is set so that the box-shadow is not blocked by the parent container. If this is not set, box-shadow will not display completely

The advantages and disadvantages

Advantages: The implementation is easy to understand

Disadvantages: Box-shadow is a performance consuming attribute, and it is unknown whether the problem of overwriting will occur depending on position:relative

Three use HTML2Canvas to draw the target content of a translucent canvas background

Specific steps:

  1. withgetBoundingClientRectGets the display location of the target content
  2. withhtml2canvasDraws the target content to the specified location and size obtained in the previous step

Core code:

let target = document.querySelector('.mid-center')
let pos = target.getBoundingClientRect()
let w = ~~pos.width
let h = ~~pos.height

let canvas = document.querySelector('#canvas')
canvas.width = document.documentElement.clientWidth
canvas.height = document.documentElement.clientHeight
let ctx = canvas.getContext("2d");
canvas.style.display = 'block'

html2canvas(target, {
    width: w,
    height: h,
}).then( (cvs) = > {
    ctx.drawImage(cvs, pos.left, pos.top)
})
Copy the code

Note that canvas.width and canvas.height must be set manually, otherwise the default is 300 * 150, which will cause the canvas to be stretched if the width and height are set in the style.

The advantages and disadvantages

Advantages: The performance should be relatively better (if html2Canvas performance is poor), with canvas implementation, it is less likely to encounter problems of various levels of occlusion or incomplete display.

Disadvantages: The implementation method is relatively cumbersome, and need to use external tools

Implement four to make all other elements translucent. Then add a black background to the body

Specific steps:

  1. For the outermost element of the entire document, set a black background
  2. Walk through the document and make both the non-target content, and the parent of the non-target content, translucent

Core code:

function showGuidance() {
    let main = document.querySelector('.main')
    main.className += ' darkBackGround'
    setOpticity(main)
}

function setOpticity (element) {
    let doms = Array.from(element.children) || []
    let hasMatched = false
    for (let el of doms) {
        if(! el.className.match(/mid-center/i) && el.children.length) {
            hasMatched = setOpticity(el)
        if(! hasMatched) el.className +=' halfTransparent'
        } else if(el.className.match(/mid-center/i)) {
            hasMatched = true
        } else {
            el.className += ' halfTransparent'}}return hasMatched
}
Copy the code

If you accidentally make the parent of the target element translucent, it will become transparent even if the target element is not translucent, because everything inside the parent element will be transparent

The advantages and disadvantages

Advantage: feel no advantage ha

Disadvantages: Batch operation of DOM, dom elements in the case of poor performance

The last

All of the above implementation, according to the simplest implementation, did not consider some special cases (such as :resize, animation, etc.) attached source code