# 【canvas】动画原理の万有引力定律

·  阅读 10007

### 1. 用向量来思考问题

``````fx = f * Math.cos(angle)
fy = f * Math.sin(angle)
ax = fx / ball.m
ay = fy / ball.m
vx += ax
vy += ay
ball.x += vx
ball.y += vy

``````class Vector {
constructor(x, y) {
this.x = x
this.y = y
}
scale(n) {
this.x *= n
this.y *= n
return this
}
mag() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
normalize() {
var m = this.mag()
if (m != 0 && m != 1) {
this.scale(1 / m)
}
return this
}
this.x += other.x
this.y += other.y
return this
}
sub(other) {
this.x -= other.x
this.y -= other.y
return this
}
return new Vector(one.x + other.x, one.y + other.y)
}
static sub(one, other) {
return new Vector(one.x - other.x, one.y - other.y)
}
static dist(one, other) {
var dx = one.x - other.x
var dy = one.y - other.y
return Math.sqrt(dx * dx + dy * dy)
}
}

``````a = f.scale(1 / ball.m)

### 2. 动画原理

``````var dist = Vector.dist(sun.p, earth.p)
var f = sun.m * earth.m / (dist * dist)

``````function gravity (sun, earth) {
var dist = Vector.dist(sun.p, earth.p)
var f = sun.m * earth.m / (dist * dist)
var vec = Vector.sub(sun.p, earth.p)
return vec.normalize().scale(f)
}

``````var g = gravity(sun, earth)
var a = g.scale(1 / earth.m)

### 3. 实现

``````class Ball{
constructor() {
this.p = new Vector(0, 0)
this.m = 0
this.color = 'white'
}
draw(context) {
context.save()
context.translate(this.p.x, this.p.y)
context.beginPath()
context.arc(0, 0, this.radius, 0, 2 * Math.PI)
context.fillStyle = this.color
context.fill()
context.restore()
}
}

``````var sun = new Ball()
sun.color = 'red'
sun.p = new Vector(canvas.width / 2, canvas.height / 2)
sun.m = 1000

var earth = new Ball()
earth.color = 'aqua'
earth.p = new Vector(canvas.width / 2 + 100, canvas.height / 2 + 80)
earth.m = 1

``````;(function drawFrame() {
window.requestAnimationFrame(drawFrame)
context.clearRect(0, 0, canvas.width, canvas.height)
var g = gravity(sun, earth)
var a = g.scale(1 / earth.m)
earth.draw(context)
sun.draw(context)
})()

``````var v = new Vector(-0.3, 1)

``````var v = new Vector(-0.8, 1).scale(2.2)

2019年末，本人立了个flag，2020年要研究透canvas动画技术。

（图中二维码是我的唯一微信号，如有掘友想加的，麻烦备注下【掘金】哈。）