# 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 on`Station B`study.

One day at`Station B`When learning, discover`Station B`The 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)

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)

Besides, there’s a little girl’s`blink`Special 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 pictures`blink`Special 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));``````

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

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);``````

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 all`png`Format, we can use positioning to stack them together.

Create a new one directly`index.html`The contents are as follows:

``````<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 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:

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 directly`JS`To set it up, let’s use it here`Jquery`, in`body`Post introduction`jquery`And then write our`javascript`Script (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).

## Making blink effects

Our static page has been made almost, let’s use it next`JS`Simple implementation`blink`Special 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");

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 our`blink`Special effects! (as shown in the figure below)

As shown above, our`blink`Special 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 from`Station B`In 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 and`Station B`The original is very similar! (as shown in the figure below)

Well, it’s done!

## summary

After a simple step analysis, we combine several pictures to simulate`Station B`Autumn theme effect!

This case is found in a study (daze)`Station B`Autumn 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：`Shenzhen``Wuhan`

Welcome to send resume to email`[email protected]`, or add the following wechat remarks`Mingyuanyun`Have a consultation!

## 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 […]