Recently, I suddenly became interested in Canvas animation, and then I read some articles on a whim. To be clear in advance, I am only a code porter for some original works. Let me just take a screenshot and tell you what I think.

[My thoughts] : Actually, I want to do one of the most popular things on the Internet, where you cover your eyes with your hands while typing in your password, but forgive me, I want to do one of those special effects where you hit the minions with a mallet or lightning stun them while typing in your password, hopefully with sound effects… But the effect is not very good, can be used but not perfect on the right, because to achieve the purpose of learning and time reasons, do not continue to do, later have time may do, or you CSS great help me complete, finish the excellent special effects remember to throw the link I a face ~ very grateful. The code is at the bottom —

Snow falling scene

Again, I’m just a code porter, first of all, the scene of snow falling. Reference article click here — Canvas to achieve snow falling, the article posted the code, it can be used directly, but there is no comment, since it is a preliminary study of canvas and animation, to be reasonable, there is no comment, really don’t understand, so I here to parse the code. The effect is as follows:

Focus on an appropriate background image

Don’t blow not black, personal feel my aesthetic is very good, the snow effects need to match the background a high contrast, otherwise your background color is light color in the winter, then float white snowflakes, actually I don’t feel very clear, so looking for a long time, found this anime Christmas background, time in the evening, there are snowflakes cooperated lamplight, or very clear ~

Point 2: Canvas draws snowflakes

  • First, you need to define some parameters related to the scene, such as the speed, position and direction of the snow falling. The code is as follows:
// store all the snowflakes const snows = []; // The acceleration of falling const G = 0.015; // FPS = 60; // FPS = 60; // FPS = 60; Const SPEED_LIMIT_X = 1; const SPEED_LIMIT_Y = 1;Copy the code
  • Define the snowflake constructor
/** * Snowflake object * @param {x} x * @param {y} y * @param {radius} radius */functionSnow(x, y, radius) { this.x = x; this.y = y; This. Radius = radius; // If it is a circle, it is a radius, otherwise it is a square with the same length and width. [-1, 1] this.speed_x = 0; This. Speed_y = 0; // This. // This. Deg = 0; // X direction, falling speed parameter, falling effect > 0 left float; This.ax = math.random () < 0.5? : 0.005-0.005; }Copy the code
  • Generate a snowflake
New Snow(math.random () * W, 0, math.random () * 15 + 5); new Snow(math.random () * W, 0, math.random () * 15 + 5);Copy the code
  • Adds methods to draw and update the position of a snowflake
// Draw the snowflake snow.prototype.draw =functionConst radius = this.radius; const radius = this.radius; // Save the current state of the canvas, because the following uses transform coordinates and rotate the canvas ctx.save(); /** * The following changes are also important, because the rotation is at the origin of the canvas * therefore, if you want the snowflake to rotate clearly, you need to move the canvas coordinates to the point where the snowflake is * if you do not convert the coordinates, then all the snowflakes will rotate in the upper left corner at the origin, x and y will not change. */ // Move the origin of the canvas to the position (x, y). Canvas defaults to (0, 0) ctx.translate(this.x, this.y); Ctx.rotate (this.deg * math.pi / 180); // Draw the snowflake image because the canvas coordinates moved to (x, y), (-radius, radius) CTX. DrawImage (snowImage, -radius, -radius, radius * 2, radius * 2); Ctx.restore (); // Restore canvas rotation, translate, etc.; // Restore canvas rotation, translate, etc.; // Restore canvas rotation, translate, etc.; }Copy the code
// Update snow.prototype. update =functionConst deltaDeg = math.random () * 0.6 + 0.2; This.speed_x += this.ax; // Change direction when x goes too fast to the left or rightif(this.speed_x >= SPEED_LIMIT_X || this.speed_x <= -SPEED_LIMIT_X) { this.ax *= -1; } // Snowflakes fall at a maximum speed of 1if(this.speed_y < SPEED_LIMIT_Y) {this.speed_y += G; } this.deg += deltaDeg; This.x += this.speed_x; This. y += this.speed_y; }Copy the code
  • In this case, we use the requestAnimationFrame API provided by the browser specifically for animation. By passing in a loop function as a parameter, the API will continuously redraw to form the animation effect.
/** * Main loop function, generate snowflake and draw update snowflake position */function loop() {// Erase the current canvas, otherwise the original snowflakes will not disappear, and the new snowflakes will look like a solid white falling snowflake ctx.clearRect(0, 0, W, H); ^_^ const now = date.now (); ^_^ const now = date.now (); DeltaTime = nowlasttime; // deltaTime = nowlasttime; LastTime = now; Timer += deltaTime; // Add snowflake when timer > snowLevelTime; // Add snowflake when timer > snowLevelTime; /** * If there is no control, there will be a lot of snowflakes, between 150 and 300 are suitable */if"// draw the new snowflake, while x is a random number, y is the top 0, New Snow(math.random () * W, 0, math.random () * 15 + 5)); timer %= snowLevelTime; } const length = snows.length; snows.map(function (s, i) {
  s.update();
  s.draw();
  if(s.y >= H) { snows.splice(i, 1); }}); // To avoid distortion, the browser calls requestAnimationFrame(loop) before each page redraw; }Copy the code

Minions effect

I’m just a code hauler. Here’s another great guy who wrote a very detailed article, CSS3 Hand painted Minions. I just extended the code to make it work at most screen resolutions. Here is not to write the process, the article is really very clear ~

stun

Vertigo effect in fact, I also want to find ready-made code, I like to stand on the shoulders of giants, but I can not find, even the picture can not find, finally no way, write their own, a simple realization of the vertigo effect, as for vertigo rotation animation, the following will be a simple introduction:

  /* CSS */
 .circle-container {
      position: relative;
      width: 45px;
      height: 45px;
      transform: rotate(180deg);
    }
    .one-circle {
      position: absolute;
      width: 45px;
      height: 45px;
      background-color: #fff;
      border-left: 3px solid # 333;
      border-top: 3px solid # 333;
      border-radius: 50%; 
    }
    .two-circle {
      position: absolute;
      top: 9px;
      width: 34px;
      height: 34px;
      background-color: #fff;
      border-right: 3px solid # 333;
      border-bottom: 3px solid # 333;
      border-radius: 50%; 
    }
    .three-circle {
      position: absolute;
      bottom: 10px;
      left: 8px;
      width: 23px;
      height: 23px;
      background-color: #fff;
      border-top: 3px solid # 333;
      border-left: 3px solid # 333;
      border-radius: 50%; 
    }
    .four-circle {
      position: absolute;
      bottom: 0px;
      right: 6px;
      width: 13px;
      height: 13px;
      background-color: #fff;
      border-bottom: 3px solid # 333;
      border-right: 3px solid # 333;
      border-radius: 50%; 
    }
  /* Html */
  <div class='circle-container'>
    <div class="one-circle">
      <div class="two-circle">
        <div class="three-circle">
          <div class="four-circle"></div>
        </div>
      </div>
    </div>
  </div>
Copy the code

Both the code and the implementation are quite simple, but how to be original, or write it out, O(∩_∩)O haha ~

Intersections such as intersections ah, only to find that even the front end, there are so many branches, really like Zhang Xinxu teacher self introduction, the front part of the former engineer, I feel that the front and the back of the business of each direction is worth in-depth research ah, but I still mixed hodgebodge at this stage. Since I am interested in animation and have run out of Canvas, I also want to know about other implementation methods. By the way, I will learn briefly. Here is my learning experience.

Here are some ways to implement browser animation:

SetTimeout and setInterval

The original method is to use window.settimout () or window.setInterval() to continuously update the state and position of elements. The premise is that the image should be updated 60 times per second to create a smooth animation for the naked eye.

I’m not going to code this one. To be honest, no one should be animating in this way. If so, you’re worried about the performance of your page

CSS3’s Transition and Transform properties

A transtion can be understood as a transition, a continuous change between two points. When you combine transform and transition, you create a simple animation. The rule of transtion animation is to define the corresponding property. For example, IF I want the width to change, I will define the property as width, the change duration, that is, how long to complete the transformation, and finally change the value of the property defined in the specified event.

< span style = "box-sizing: border-box; color: RGB (255, 255, 255); height: 128px; transition-property: width,height; transition-duration: 2s; -moz-transition-property: width,height; /* Firefox 4 */ -moz-transition-duration: 2s; /* Firefox 4 */ -webkit-transition-property: width,height; /* Safari and Chrome */ -webkit-transition-duration: 2s; /* Safari and Chrome */ -o-transition-property: width,height; /* Opera */ -o-transition-duration: 2s; /* Opera */ } .ball:hover { width: 256px; height: 256px; }Copy the code

CSS3 animation and KeyFrames

Different from Transition and Transform, animation can be directly understood as animation, and I think it is more powerful. As mentioned above, the animation CSS is created for animation. It can do most of the simple animation effects. It needs to define an animation effect name and then define the effect through keyFrame. Here I simply implemented a basketball free-fall effect, very crude, just a simple demo:

.ball-animation { position: absolute; width: 128px; height: 128px; transform: rotate(0); animation: ball-drop 6s linear; animation-fill-mode: forwards; -webkit-animation: ball-drop 6s linear; -webkit-transform: rotate(0); -webkit-animation-fill-mode: forwards; } @keyframes ball-drop { 0% { transform: rotate(0); top: 0 } 10% { transform: rotate(60); top: calc(var(--height) * 1px ); } 20% { transform: rotate(120); top: 40px; } 30% { transform: rotate(240); top: calc(var(--height) * 1px ); } 40% { transform: rotate(300); top: 80px; } 50% { transform: rotate(360); top: calc(var(--height) * 1px ); } 60% { transform: rotate(60); top: 160px; } 70% { transform: rotate(120); top: calc(var(--height) * 1px ); } 80% { transform: rotate(180); top: 380px; } 90% { transform: rotate(240); top: calc((var(--height) - 20) * 1px ); } 100% { transform: rotate(260); top: calc(var(--height) * 1px ); }}Copy the code

Although the implementation is very rough, BUT I still wrote things like shadows, so it is true, haha. Detailed introduction I do not say, I think to read zhang Xinxu teacher’s article can be easy to understand, portal

requestAnimationFrame

Since the API is the most important thing to do with canvas animation, I’ll leave it at the end. It’s highlighted in the MDN: If you want to generate another animated frame on the next redraw, your callback routine must call requestAnimationFrame(). So in other words, you have to call this API if you want to keep redrawing and animate it.

Window. RequestAnimationFrame () method tells the browser you want to perform the animation and request the browser before the next redraw call the specified function to update the animation. This method takes a callback function as an argument, which is called before the browser redraws. You can control how many times you want to refresh. RequestAnimationFrame () will return an ID for the shape. With this ID you can call cancleAnimationFrame(ID) to stop animation with the following code:

let timeoutId;
letanimateId; const fps = 20; / / window. For example, I just want to refresh the 20 times per second requestAnimationFrame = (function () {
    return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        timeoutId = setTimeout(callback, 1000 / fps);
      }
  })();
}
function loop() {animateId = requestAnimaitonFrame(loop); } requestAnimationFrame clearTimeout(timeoutId);} requestAnimationFrame clearTimeout(timeoutId); cancleAnimationFrame(animateId);Copy the code

RequestAnimationFrame () performs better than setTimeout and setInterval forms. In most browsers, requestAnimationFrame() performs better than setTimeout or setInterval. When running in a background TAB or hidden, requestAnimationFrame() suspends calls to improve performance and battery life.

Compare animation and requestAnimationFrame

In fact, do not have to know that the same animation effect, with pure CSS3 implementation and use the requestAnimationFrame js implementation means, certainly CSS3 performance is higher. Here is a comparison of the rendering time of the same action: animation:

requestAnimationFrame

Well, THIS is a fake test. I think first of all, I didn’t control the consistency of the speed. Second, I used calc function to calculate the position in the annimation implementation.

Strong disclaimer: I’m just comparing for results, I don’t mean one is higher or lower, I think I’ll use it according to the situation

Where improvements can be made

The final implementation of the code has a lot of places can be improved, here to record, in case of which god in a good mood to change how to do, O(∩_∩)O haha ~.

  • The mallet can be drawn using CSS3 and then hit the minion’s head to produce a banging and stun sound
  • When the snow falls into the shadows, minions, and input boxes, it should stay there to make it more realistic
  • Snowflakes falling on the ground should form snow, but too much snow will affect the performance. It is easy to add ~ ~ to determine the location of snowflakes and specify that snowflakes do not redraw.
  • Forgive me for not doing mobile terminal adaptation, the following demo try not to use the mobile phone to open… Pad might be ok, O(∩_∩)O haha ~

conclusion

I have watched the animation briefly in these two days, and I feel that the front end is as deep as the sea. At present, I plan to dabb in all the things I am interested in, and then choose a direction slowly

Only clone not star, not enough meaning oh, I will curse your ^_^ in my heart