Because at ordinary times is also focused on netease UEDC subscription number, a few days ago to see such a move, theme is “netease cloud music listening to report” for 2018, is a person in efforts to push the car because the composition is simple, creative and good, so I tried to use the difficulty of SVG + CSS animations to implement, probably takes about two hours, the efficiency is high, It’s much faster than using AE. Here’s how it works.

1. The first step is composition, which takes an hour

It’s hard to get an artist for something like drawing. It was done in Ai, not too much detail (there were gradients and noises in the original effect, so I left them out and filled them with solid colors instead, after all, I was a team and I was alone in the battle).

2. The second step is to increase the rotation effect of the legs, which takes 0.5 hours

In fact, it is a path to do this realization effect involving the joint class, because in short, it is all rotation animation, but it is to increase the linkage, that is to say, the rotation of the thigh around the joint (i.e. the origin) should drive the rotation of the leg around the end of the thigh (the origin corresponding to the leg animation). With the foundation of a dancing robot, this is a lot easier, but it’s still a little optimized, and instead of splitting up a lot of SVG into robots, it’s nested directly.

First, and most importantly, get the values of the three coordinates in the figure below. This is an essential tranForm-Origin value for doing rotation animations.

The rotation of the thigh is very simple with the rotation animation set. Take the left leg as an example. By comparing the left and right legs, the data is approximately 60 degrees clockwise, just define the animation parameters in CSS as follows:

/* Thigh rotation animation rules */
@keyframes legLMove{
0% {transform: rotate(0deg)}
100% {transform: rotate(-60deg)}
}
#legL{
animation: legLMove 1s  infinite  alternate;
transform-origin:455px 235px; /* The origin of the thigh rotation movement */
}
Copy the code


<! -- Left thigh -->
<g id="legL">
	<path d="M... z"/>
</g>
<! -- Left calf -->
<g id="calfL">
    <path d="M... z"/>
</g>
Copy the code

Since you want to follow the thigh movement, it is easy to do, directly put the whole part of the left calf into the combination

TAB where the thigh is, you can ensure the same movement. The modified DOM structure now looks like:

<! -- Left thigh -->
<g id="legL">
	<path d="M... z"/>
	<! -- Left calf -->
	<g id="calfL">
    	<path d="M... z"/>
	</g>
</g>
Copy the code

@keyframes calfLMove{
0% {transform: rotate(0deg)}
100% {transform: rotate(100deg)}
}
#calfL{
animation: calfLMove 1s  infinite alternate;
/* The rotation origin of the lower leg is the end of the thigh */
transform-origin:343px 220px; 
}
Copy the code

In this way, the calf follows the thigh to carry on the rotation movement while realizing his rotation effect. (The method implemented here is much more optimized than when I was doing the dancing robot).

The left leg is done, the right leg is done, but in reverse. Remember to modify the DOM structure.

offset-rotate:var(--degMove);
document.documentElement.style.setProperty

3. The third step is to increase the dynamic effect of notes, which takes 0.5 hours

In order to keep the original effect as consistent as possible, the dynamic effects of the notes have been added. To make it easier to see, I hid the irrelevant elements temporarily and kept only the notes. The general effect was as follows:

Move along the path | change | becomes weak

@keyframes notePath{
0% {offset-distance:0%;}
100% {offset-distance:100%;}
}
#notePath{
offset-path:path(' '); /* Draw the path corresponding to the d attribute */
animation:notePath 2s ease infinite;
}
Copy the code

Call this animation property to get the notes moving along the path ** without scaling the notes, using the intermediate state as the baseline. (Again, in path animation, it is important to export the element at zero on the canvas.) * * :

The definition of the transform: scale ()

@keyframes notePath{
0% {
offset-distance:0%;
transform:scale(0.2); /* Add the definition of scaling to shrink the starting point to 0.2*/100%} {offset-distance:100%;
transform:scale(1.5); /* Add the definition of scaling to enlarge the end point to 1.5 times the original size */}}Copy the code

At this point, the note moves along the path with the effect of scaling superimposed:

@keyframes notePath{
0% {
offset-distance:0%;
transform:scale(0.2);
}
50%{opacity: 1} /* Add a definition of transparency at the halfway point */
100% {
offset-distance:100%;
transform:scale(1.5);
opacity: 0.1}}Copy the code

Try to fool the browser.
opacity:1


@keyframes notePath{
0% {
offset-distance:0%;
transform:scale(0.2);
opacity: 2; /* Transparency set >1*/100%} {offset-distance:100%;
transform:scale(1.5);
opacity: 0.1; }}Copy the code

For the browser, during its execution, opacity comes from 2→0.1 during the whole time period, so the first half of the period is almost 2→1 (corresponding to no change in transparency), and the second half of the period is 1→0.1 (for decreasing transparency), which meets our setting. The second method, though a little more troublesome, is an important one. One problem with the above Settings is that since the animation property is a uniform one, it contains a lot of parameters, such as speed, which I defined as ease. What if I want transparency to change linearly at a rate? Let’s try superimposing multiple rules on animation properties

/* Add an animation rule that sets transparency changes */
@keyframes noteOpacity{
	50%{opacity:1100%} {opacity:0.1}}Copy the code

In this case, we need to append the opacity change animation rule to the animation definition. We can append the new animation rule property after the comma.

animation:notePath 2s ease infinite ,noteOpacity 2s linear infinite;
/* The new animation rule noteOpacity allows you to define other animation properties */
Copy the code

This overlay of multiple animation rules (of course, you have to assume that each animation rule defines a different property change) can be useful in some scenarios. So let’s do a very simple experiment with this. When I change the animation time of noteOpacity animation rule from 2s to 0.5s, in order to see the difference, the time of path animation is delayed to 5s. Guess what will happen to the animation effect?

  1. For linkage effects, place the whole part in the sibling of the element to be linked to maintain the same animation Settings, and then set separate animation properties.
  2. Adding different animation rules to an animation property is very, very useful.

I am also in the process of doing CSS animation, constantly to optimize the original summary of knowledge system, in the future encounter interesting cases will do a do. CSS variables are new to me, although they’re two years old. I’m ready to see how they work with JAVASCRIPT. It’s much simpler than adding a

4. Enhanced version to do a can arbitrarily speed up the effect of deceleration

The effect of increasing or decreasing the speed of interaction was not intended in this case, but someone mentioned it in the comments, so give it a try. To be clear, acceleration and deceleration change the amount of time required for the animation cycle in the animation property. In this case, the four animation times are the same, so instead of specifying the time, write var(–speed) as a way to define variables. For example, the animation properties of the original left leg leg are as follows:

animation: legLMove 1s  infinite  alternate;
Copy the code

With the global variable definition changed to:

animation: legLMove var(--speed)  infinite  alternate; 
/* Replace specific time definitions with variables */
Copy the code

When the page loads, we need to initialize **–speed first, so we define a variable time and initialize it to 1. Then through the document. The documentElement. Style. SetProperty (” speed “, the time + “s”) – this approach to speed * * variables defines a initial value 1 s.

Var (–speed, 1s); var(–speed, 1s); var(speed, 1s);

Now comes the most important part, setting up the listening events for keyboard presses. The keyboard listener event document.onKeyDown also works in SVG, regardless of browser compatibility. Since it is simple to speed up and slow down, I only specify two buttons, left and right arrows, and want to get the effect of pressing the left arrow to slow down and the right arrow to speed up.

For the animation effect of acceleration and deceleration, corresponding to the animation time is just the opposite, the longer the time, the slower the speed, therefore, each time after pressing the left arrow let time+1, the speed will be slower accordingly; For acceleration, since time can only be positive, it is set to time/(time+1). (There are many methods defined here, just one of them chosen randomly). The final javascript section looks like this:

var time=1;
// Give an initial setting before the keyboard event is triggered.
document.documentElement.style.setProperty("--speed",time+"s");
document.onkeydown= function(e){
    / / left head
    if(e.keyCode==37){time+=1; }/ / right arrow
    if(e.keyCode==39){time=time/(time+1); }document.documentElement.style.setProperty("--speed",time+"s");
    }
Copy the code

Ok, now that I’m ready to try it out, I added a text tag

to the original SVG structure to show the key value of the key.

Observe the key value in the lower right corner

The CSS method of defining variable attribute values is much nicer than the innerHTML method of appending style attributes by creating a