First look at the plane drag effect:

There are also horizontal drag-and-drop versions:

First of all, the spring effect was inspired by the second reference book.

I don’t know if this is too complicated for you, but it took me about an hour to finish it.

This article will introduce the specific principle of the realization in detail, after understanding the research, the kinematics of animation should also be a pass.

1. General principles of kinematics

Let’s start with the basic principles of motion animation.

We know that we can animate the ball by updating its coordinates in real time according to the requestAnimationFrame.

ball.x += 3
ball.y += 4
Copy the code

Each frame, the ball moves 3px to the right and 4px down. 3 and 4 are the descriptions of the velocities. So we can define them as horizontal velocity and vertical velocity.

vx = 3
vy = 4
ball.x += vx
ball.y += vy
Copy the code

In the code above, the velocity is constant, so the motion is uniform and linear. If we want to accelerate motion, then we need to introduce acceleration:

ax = 0.5
ay = 1
vx += ax
vy += ay
ball.x += vx
ball.y += vy
Copy the code

According to niu’s law, force is proportional to acceleration.

f = m * a

We assume that the ball has a mass of one, so we can introduce a force model. For example, the projectile motion of a small ball is easy to achieve:

vx = 2.5
vy = - 6
gravity = 0.1
vy += gravity
ball.x += vx
ball.y += vy
Copy the code

The effect is as follows:

Which small ball code is still the usual implementation:

class Ball{
  constructor() {
    this.x = 0
    this.y = 0
    this.radius = 20
  }
  draw(context) {
    context.save()
    context.translate(this.x, this.y)
    context.fillStyle = 'red'
    context.beginPath()
    context.arc(0.0.this.radius, 0.Math.PI * 2)
    context.fill()
    context.restore()
  }
}
Copy the code

Speaking of forces, to simulate the motion of objects in the real world, we sometimes have to consider friction. Here we assume that the velocity of a moving object decays after every frame. Here the model is used:

friction = 0.99
vx *= friction
vy *= friction
ball.x += vx
ball.y += vy
Copy the code

Each frame speed will be discounted by 0.99 percent. 0.99 looks close to one, but it decays exponentially. Browsers typically have frame rates around 60, so 0.99 ^ 60 drops quickly to something close to zero.

The effect is as follows:

Hooke’s Law

With the general kinematics of the foundation, the next formal analysis of the opening animation principle.

In addition to gravity and friction, the ball is affected by the force of a spring.

In high school we all learned hooke’s Law: The force exerted by a spring itself is proportional to its shape.

F = k * x

Where k is the spring coefficient, determined by the spring itself. X is the shape variable of the spring.

The acting force is equal to the reacting force, and the force exerted on the ball is:

f = -k * x

Therefore, the key code of horizontal harmonic motion is:

var x = ball.x -spring.x - initLength
var f = -k * x
vx += f
ball.x += vx
spring.length = ball.x - spring.x
Copy the code

Where x is the spring variable. F is the spring force on the ball, and the last two lines of code update the ball’s speed and the current length of the spring.

There’s no friction here, so it’s going to go on forever. The effect is as follows:

In order for the ball to move, the ball is initially spread out a little bit. This distance is also the amplitude of the spring.

var amplitude = 70
ball.x += amplitude
var vx = 0
Copy the code

The spring is mainly simulated using quadratic Bezier curves.

class Spring{
  constructor(length) {
    this.x = 0
    this.y = 0
    this.angle = 0
    this.length = length
  }
  draw(context) {
    context.save()
    context.translate(this.x, this.y)
    context.rotate(this.angle)
    context.strokeStyle = 'white'
    context.beginPath()
    context.moveTo(0.0)
    var n = 16
    var h = 25
    var d = (this.length - 2 * h) / n
    context.lineTo(h, 0)
    for (var i = 0; i < n; i++) {
      var dir = i % 2= =0 ? 1 : - 1
      context.quadraticCurveTo(h + d * ( i + 0.5), 20 * dir,  h + d * (i + 1), 0)
    }
    context.lineTo(this.length, 0)
    context.stroke()
    context.restore()
  }
}
Copy the code

The following analysis of the opening effect of the implementation of the need to pay attention to the details.

3. Synthesis and decomposition of forces

Add the logic of friction and drag, and you can easily achieve the second effect. There is no further explanation here.

The first effect is a little more complicated. First, the position of the spring head should be updated every frame.

spring.x = mouse.x
spring.y = mouse.y
Copy the code

The spring force received by the ball is:

var dx = ball.x - spring.x
var dy = ball.y - spring.y
var x = Math.sqrt(dx * dx + dy * dy) - initLength
var f = -k * x
Copy the code

In order to find the horizontal and vertical accelerations, the force decomposition is needed:

According to the triangle, there are:

var angle = Math.atan2(dy, dx)
var fx = f * Math.cos(angle)
var fy = f * Math.sin(angle)
Copy the code

Finally, the logic of spring force, gravity, and friction:

vx += fx
vy += fy
vy += gravity
vx *= friction
vy *= friction
ball.x += vx
ball.y += vy
Copy the code

Another thing to notice is that after updating the ball position, because the ball position has changed, you need to calculate the new length and direction of the spring at this time.

Click here to see the final look and the full code.

Thank you for reading this and hope it helps.

In this paper, to the end.



At the end of 2019, I set a flag that I would study canvas animation technology in 2020.

(The two-dimensional code in the picture is my only wechat account. If you want to add it, please note [Gold digging].)

In this series, I want to write some common animation knowledge, this article is the fourth, the length may vary. For more information, please check out my personal homepage or series catalog.

Because of the length problem, according to the past experience, the number of likes is not too many, after all, people like to give the kind of article that can not finish reading in a short time. Yeah, I guess I do, too. ^_^

In fact, writing articles is mainly for myself, which is a witness of self-progress. It might be better to have that mindset.

In addition, I have read three books on Canvas technology. I think I passed the basics.

1. HTML5 Canvas Core Technology

2. HTML5+JavaScript Animation Basics

3. WebGL Programming Guide

Some articles in this series may refer to the knowledge system inside. For some knowledge belonging to the domain consensus, if there is partial similarity, we can only say: “How can it be regarded as plagiarism if we learn it by ourselves?” .

I’m kidding. I should mention where I got the idea. I particularly like this quote from the Elite Daily Class article:

As for the content of the article, canvas API, this series may not be prepared to introduce one by one, please forgive me for beginners. MDN all have, quite detailed. At the same time, the article encountered will be briefly mentioned. The main core is to illustrate some of the skills and principles of personal understanding of the bar. I’m also going to analyze some of the cool animations on Codepen, and if I have time I’ll probably analyze a couple of animation engines, all 2D of course.

Thank you again for reading this far. See you in the next article.