Learn “layer combination animation” from autumn theme of station B

Time:2020-10-30

Hello everyone, we are the front-end team of Mingyuan cloud.

as everyone knows,Station BIs a good website for learning, our team’s small partners are often onStation Bstudy.

One day atStation BWhen learning, discoverStation BThe autumn theme has been opened, and there is also a universe in the interaction of the head map. As we change the position of our mouse, the head map also changes with our mouse position, with the autumn theme, it appears to be particularly cured. (as shown in the figure below)

Learn

Xiaobian is also very interested in this interaction, so let’s go directly to the theme and try to achieve this animation effect!

Principle analysis

We first analyze the implementation principle and open the console. We can find that this effect is achieved by changing the position of several layers and Gaussian blur (as shown in the figure below)

Learn

Besides, there’s a little girl’sblinkSpecial effects are achieved by switching pictures. Therefore, our implementation steps are divided into four steps

  1. Get the corresponding pictures;
  2. Put the picture in the corresponding position according to the effect picture, and set the default Gaussian blur;
  3. Making by switching picturesblinkSpecial effects;
  4. Gauss and blur according to the position of the mouse;

Let’s follow the steps above and start making!

Get pictures

First, we open the console (F12) and enter the following line of code on the console to get the image.

var images = document.querySelectorAll(".animated-banner .layer img");
var urlList = [].slice.call(images).map((item) => item.src);
console.log(JSON.stringify(urlList, null, 2));

Learn

As shown in the figure above, we download these pictures to our computer (as shown below)

Learn

There is also an animation carousel. We use the following line of code to get several different images.

var animateImgList = [];
setInterval(() => {
  var imgSrc = document.querySelector(
    ".animated-banner >.layer:nth-child(2) img"
  ).src;
  if (!animateImgList.includes(imgSrc)) {
    console.log(imgSrc);
    animateImgList.push(imgSrc);
  }
}, 200);

Learn

As shown in the figure above, we can get several pictures in different states, which we can download to our computer.

Display pictures

The pictures we downloaded are allpngFormat, we can use positioning to stack them together.

Create a new one directlyindex.htmlThe contents are as follows:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .img-list {
      width: 100%;
      min-width: 1000px;
      height: 155px;
      position: relative;
      overflow: hidden;
    }
    .img-list .layer {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  </style>
  <body>
    <section class="img-list">
      <div class="layer">
        ![](./assets/1.png)
      </div>
      <div class="layer">
        ![](./assets/2_1.png)
      </div>
      <div class="layer">
        ![](./assets/3.png)
      </div>
      <div class="layer">
        ![](./assets/4.png)
      </div>
      <div class="layer">
        ![](./assets/5.png)
      </div>
      <div class="layer">
        ![](./assets/6.png)
      </div>
    </section>
  </body>
</html>

A simple picture arrangement is made above, and the effect is shown in the following figure:

Learn

As can be seen from the above figure, we have a preliminary prototype after stacking multiple images. Next, let’s set the default Gaussian blur.

Since our position offset and Gaussian blur need to be interactive later, we use it directlyJSTo set it up, let’s use it hereJquery, inbodyPost introductionjqueryAnd then write ourjavascriptScript (below).

<script></script>
<script>
  const imgList = $(".img-list .layer img");
  //Default position offset and Gaussian blur value
  const defaultStyles = [
    { translateX: 0, translateY: 0, blur: 4 },
    { translateX: 0, translateY: 0, blur: 0 },
    { translateX: -50, translateY: 0, blur: 1 },
    { translateX: 0, translateY: 4.2, blur: 4 },
    { translateX: 0, translateY: -1.8, blur: 5 },
    { translateX: 0, translateY: 0, blur: 6 },
  ];

  function setDefaultImgStyle() {
    for (let i = 0; i < imgList.length; i++) {
      const imgItem = imgList[i];
      const defaultStyle = defaultStyles[i];
      const { translateX, translateY, blur } = defaultStyle;
      //Set position offset and Gaussian blur
      $(imgItem).css({
        //Position offset
        transform: `translate(${translateX}px, ${translateY}px)`,
        //Gaussian blur
        filter: `blur(${blur}px)`,
      });
    }
  }
  setDefaultImgStyle();
</script>

After setting the position offset and Gaussian blur, our static page is completely consistent with the rendering (as shown below).

Learn

Making blink effects

Our static page has been made almost, let’s use it nextJSSimple implementationblinkSpecial effects.

This is relatively simple. We only need to set a timer to switch the image set every 3 seconds. The code implementation is as follows:

function setShakeAnimation() {
  //The second picture of the little girl
  const imgGirl = $(".img-list .layer:nth-child(2) img");

  //Blink your eyes every 3 seconds
  setInterval(() => {
    //Half closed eyes
    $(imgGirl).attr("src", "./assets/2_2.png");

    //Close your eyes completely after 100 ms
    setTimeout(() => {
      $(imgGirl).attr("src", "./assets/2_3.png");
    }, 100);

    //Half open your eyes after 300 milliseconds
    setTimeout(() => {
      $(imgGirl).attr("src", "./assets/2_2.png");
    }, 300);

    //Fully open your eyes after 400 milliseconds
    setTimeout(() => {
      $(imgGirl).attr("src", "./assets/2_1.png");
    }, 400);
  }, 3000);
}
setShakeAnimation();

Then, let’s take a look at ourblinkSpecial effects! (as shown in the figure below)

Learn

As shown above, ourblinkSpecial effects have been able to confuse the real with the fake!

Dynamic interaction

Finally, let’s add interactive effects to our layer collection!

We start fromStation BIn the original interaction, we can find that when we put the mouse up and move left and right, the position and Gaussian blur of the image change. So we first add the mouse moving event monitoring. The code implementation is as follows:

//Screen width
const width = document.body.clientWidth;
//Mouse entry events
$(".img-list").mouseenter((e) => {
  //When the mouse leaves, the event monitoring is disabled and the status is reset
  $(".img-list").mouseleave(() => {
    setDefaultImgStyle();
    $(".img-list").off("mousemove");
    $(".img-list").off("mouseleave");
  });

  //Record position when mouse enters
  const originalX = e.pageX;
  $(".img-list").mousemove((e) => {
    //Record position when mouse is moving
    const currentX = e.pageX;
    //According to the screen width and moving distance, calculate the proportion of movement
    const offsetRatio = (currentX - originalX) / width;
    //Mouse left
    if (offsetRatio < 0) {
      setLeftImgStyle(Math.abs(offsetRatio));
      //Mouse right
    } else {
      setRightImgStyle(offsetRatio);
    }
  });
});

Next, after a rough measurement, we will find that the effect of Gaussian blur change is shown in the table below.

Picture serial number Initial value (Gaussian blur value) From rightmost to leftmost (Gaussian blur) From far left to far right (Gaussian blur)
1 4 4 -> 0 4 -> 8
2 0 0 -> 10 0 -> 8
3 1 1 -> 5 1 -> 4
4 4 4 -> 13 4 -> 0 -> 4
5 5 5 -> 14 5 -> 0 -> 4
6 6 6 -> 12 6 -> 0

The effect of position change is shown in the table below.

Picture serial number Initial value (x-axis position) From rightmost to leftmost (x-axis position) From leftmost to rightmost (x-axis position)
1 0 0 0
2 0 -9 9
3 -50 -80 21
4 0 -36 35
5 0 -78 77
6 0 -97 96

According to the above two tables, we can start to write code. The code implementation is as follows:

//The final target position after the mouse is moved to the left
const leftStyles = [
  {
    translateX: 0,
    translateY: 0,
    blur: 0,
  },
  {
    translateX: -9,
    translateY: 0,
    blur: 10,
  },
  {
    translateX: -80,
    translateY: 0,
    blur: 5,
  },
  {
    translateX: -36,
    translateY: 4.2,
    blur: 13,
  },
  {
    translateX: -78,
    translateY: -1.8,
    blur: 14,
  },
  {
    translateX: -97,
    translateY: 0,
    blur: 12,
  },
];

function setLeftImgStyle(offsetRatio) {
  for (let i = 0; i < imgList.length; i++) {
    const imgItem = imgList[i];
    const {
      translateX: defaultTranslateX,
      translateY: defaultTranslateY,
      blur: defaultBlur,
    } = defaultStyles[i];
    const leftStyle = leftStyles[i];
    //The final coordinate and Gauss blur value are calculated according to the moving proportion
    const translateX =
      (leftStyle.translateX - defaultTranslateX) * offsetRatio +
      defaultTranslateX;
    const blur = (leftStyle.blur - defaultBlur) * offsetRatio + defaultBlur;

    //Set position offset and Gaussian blur
    $(imgItem).css({
      //Position offset
      transform: `translate(${translateX}px, ${defaultTranslateY}px)`,
      //Gaussian blur
      filter: `blur(${blur}px)`,
    });
  }
}

//Final target position after mouse right movement
const rightStyles = [
  {
    translateX: 0,
    translateY: 0,
    blur: 8,
  },
  {
    translateX: 9,
    translateY: 0,
    blur: 8,
  },
  {
    translateX: 21,
    translateY: 0,
    blur: 4,
  },
  {
    translateX: 35,
    translateY: 4.2,
    blur: [0, 4],
  },
  {
    translateX: 77,
    translateY: -1.8,
    blur: [0, 4],
  },
  {
    translateX: 96,
    translateY: 0,
    blur: 0,
  },
];

function setRightImgStyle(offsetRatio) {
  for (let i = 0; i < imgList.length; i++) {
    const imgItem = imgList[i];
    const {
      translateX: defaultTranslateX,
      translateY: defaultTranslateY,
      blur: defaultBlur,
    } = defaultStyles[i];
    const rightStyle = rightStyles[i];
    let rightBlur = rightStyle.blur;
    let blur = defaultBlur;
    //The final coordinate and Gauss blur value are calculated according to the moving proportion
    const translateX =
      (rightStyle.translateX - defaultTranslateX) * offsetRatio +
      defaultTranslateX;
    if (Array.isArray(rightBlur)) {
      const targetBlur = offsetRatio < 0.5 ? rightBlur[0] : rightBlur[1];
      const ratio =
        offsetRatio < 0.5 ? offsetRatio * 2 : (offsetRatio - 0.5) * 2;
      const currentBlur = offsetRatio < 0.5 ? defaultBlur : rightBlur[0];
      blur = (targetBlur - currentBlur) * ratio + currentBlur;
    } else {
      blur = (rightBlur - defaultBlur) * offsetRatio + defaultBlur;
    }
    //Set position offset and Gaussian blur
    $(imgItem).css({
      //Position offset
      transform: `translate(${translateX}px, ${defaultTranslateY}px)`,
      //Gaussian blur
      filter: `blur(${blur}px)`,
    });
  }
}

In the above code implementation, we add the image position offset and Gaussian blur value in the process of moving the mouse left and right. Finally, we achieve the effect of andStation BThe original is very similar! (as shown in the figure below)

Learn

Well, it’s done!

summary

After a simple step analysis, we combine several pictures to simulateStation BAutumn theme effect!

This case is found in a study (daze)Station BAutumn theme is very interesting, here to share with you, with a few pictures of such a creative interaction, is also very interesting~

thirst after talents

Mingyuan cloud chain front-end team is a passionate team, Mingyuan cloud is also a company that attaches great importance to technology.

We have perfect welfare: Six insurances and one fund + (rich) year-end bonus + paid leave + communication subsidy

Our working atmosphere: flexible work, flat structure, advocating simple and efficient Internet culture with problem-solving as the core, encouraging technology innovation and sharing, and holding technical competitions such as hacker Marathon (the highest prize of 3W), geek competition and mobile community every year

We have humanistic care: fancy afternoon tea (every week), birthday gift, free travel, activity funds, wedding gift, free physical examination

We also have a wealth of amateur club activities: basketball, football, yoga, badminton, billiards, chess and card games

The positions we are looking for are:(middle and senior) front end Engineer(middle and senior) test engineer(middle and senior) Java Engineer(Senior) PHP Engineer

Base:ShenzhenWuhan

Welcome to send resume to email[email protected], or add the following wechat remarksMingyuanyunHave a consultation!

Learn

Recommended Today

Layout of angular material (2): layout container

Layout container Layout and container Using thelayoutDirective to specify the layout direction for its child elements: arrange horizontally(layout=”row”)Or vertically(layout=”column”)。 Note that if thelayoutInstruction has no value, thenrowIs the default layout direction. row: items arranged horizontally.max-height = 100%andmax-widthIs the width of the item in the container. column: items arranged vertically.max-width = 100%andmax-heightIs the height of the […]