Front end daily combat No. 176: using perspective to show the relationship between HTML, CSS and JS

Time:2020-10-23

(the reason for the photo review, so please check the 7 screenshots of the development process in my microblog:https://weibo.com/6063054508/…

I came across this picture earlier this year,I put it on my microblog,Recently, I took time to make them into interactive pages. This paper records the development process.

Effect preview

Press the “click preview” button on the right to preview on the current page, and click the link to preview in full screen.

https://codepen.io/comehope/pen/GRqpLGX

Source code download

For the full source code of daily front end combat series, please download it from GitHub:

https://github.com/comehope/front-end-daily-challenges

Interpreting code

1、 Prepare material

First prepare 3 pictures for development, file names arehtml.pngcss.pngjs.pngHtml is similar to human skeleton, CSS to human appearance, JS to human nervous system
https://assets.codepen.io/947795/html.png
https://assets.codepen.io/947795/css.png
https://assets.codepen.io/947795/js.png

2、 DOM structure

The container name is.person, which represents a person’s appearance, contains a child element.insideIt means that the inside of the body that the person is exposed to is the bones, blood vessels and so on.

<div class="person">
    <div class="inside"></div>
</div>

3、 Present the normal state of human beings

Center elements on the page:

body {
    margin: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

Put the picturecss.pngAs a container.personBackground image of:

.person {
    width: 320px;
    height: 537px;
    background-image: url(css.png);
}

The effect is as follows:
< Fig

4、 Showing human bones

Put the picturehtml.pngAs an element.person .insideBackground image of.

.person .inside {
    width: 100%;
    height: 100%;
    background-image: url(html.png);
    background-position: center;
}

The effect is as follows:
< Figure 2 >

Add to the picture5pxThe gray border of the.

.person .inside {
    box-sizing: border-box;
    border: 5px solid gray;
    border-radius: 0.3em;
}

The effect is as follows:
< Figure 3 >

Reduce the height of the border to100px, and locate in the upper middle of the container, which is the perspective window that will slide up and down in the future.

.person {
    position: relative;
}

.person .inside {
    /*height: 100%;*/
    height: 100px;
    position: absolute;
    top: 25%;
}

The effect is as follows:
< Figure 4 >

If you look at the picture carefully, there is a mistake. The perspective window is in the chest, but the perspective area is the waist. So we need to usebackground-attachment: fixed;Lock the picture in a fixed position. Please note that this property value is the core of the whole work, otherwise the perspective window will not slide.

.person .inside {
    background-attachment: fixed;
}

The effect is as follows:
< Fig

At this point, the static layout is complete.

5、 Perspective window sliding effect

Next, we deal with the sliding effect of the perspective window following the mouse.

The program entry isinitFunction, where 2 variables are declaredpersonandinside, representing their corresponding DOM elements.

window.onload = init

function init() {
    var person = document.querySelector('.person')
    var inside = document.querySelector('.person .inside')
}

bypersonElement bindingmousemoveEvent, which is updated when the event is triggeredinsideElementaltopProperty value to form a sliding effect.

function init() {
    person.addEventListener('mousemove', function (e) {
        inside.style.top = getTopPosition(e.offsetY)
    });
}

topProperty values of thegetTopPosition()Function, whereoffsetThe value is half the height of the perspective window, which means that the mouse pointer is in the middle of the perspective window when it is sliding. After detecting the sliding position and not running out of the container, return to the position and add the unit herepx

function getTopPosition(y) {
    const windowHeight = 100
    var offset = windowHeight / 2
    if(y < offset) return
    if(y > (Number.parseInt(window.getComputedStyle(person).height)) - offset) return
    return y - offset + 'px'
}

Now refresh the page and see that there is already a sliding effect, but it is not smooth, because of the sub elements.insideLocated in container.personAbove, the event of the child element will be triggered first. For this purpose, we use thepointer-events: none;Prevents child elements from responding to mouse events.
In addition, the mouse pointer is displayed as a movable icon.

.person {
    cursor: move;
}

.person .inside {
    pointer-events: none;
}

So far, the core function development of this work has been completed.

6、 Switch Perspective

Next, add the function of switching perspective content.

Add two check boxes in DOM to select whether to perspective HTML (human skeleton) or JS (human nerve).

<div class="selector">
    <input type="radio" name="options" value="html" id="html" checked>
    <label for="html">HTML</label>
    <input type="radio" name="options" value="js" id="js">
    <label for="js">JavaScript</label>
</div>

Defining the style of the check box is not the focus of this work. It also uses common properties, so I will not explain it in detail.

.selector {
    position: absolute;
    width: 9em;
    top: calc(50% - 8em / 2);
    left: 3em;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
}

.selector input {
    width: 1.2em;
    height: 1.2em;
}

.selector label {
    font-size: 1.5em;
    font-family: sans-serif;
    cursor: pointer;
}

.selector input:checked + label {
    color: dodgerblue;
}

The effect is as follows:
< Figure 6 >

Finally, bind the click event for the check box, and update it when the check box is clicked.insideThe background image of the element.

function init() {
    var options = document.getElementsByName('options')

    options.forEach((option) => {
        option.addEventListener('click', (e) => {
            inside.style.backgroundImage = getImageUrl(e.target.value)
        })
    })
    
    function getImageUrl(opt) {
        return 'url(' + opt + '.png' + ')'
    }
}

Here is the effect of perspective neurography:
< Figure 7 >

be accomplished!

About the author

Zhang Bi, whose pseudonym is @ comehop, was caught by the infinite charm of web at the end of the 20th century. Since then, he has been fighting in the front line of web development.

Front end daily practice column is my notes on practicing project-based learning in recent years. It shows the whole process from inspiration flash to code implementation by project driven learning. It can also be used as practice exercises and development reference for front-end development.

Front end daily combat No. 176: using perspective to show the relationship between HTML, CSS and JS

My book “CSS3 art” has been published by the people’s Posts and Telecommunications Publishing House. It is printed in full color. With more than 100 vivid and beautiful examples, it systematically analyzes the important grammar of CSS and visual effects, and contains nearly 10 hours of video demonstration and explanation. Jingdong / tmall / Dangdang are available for sale.