JS water simulation test
by Yukino Song
HTML
<canvas height="250" width="100" style="filter: blur(5px) contrast(10);"></canvas>
JavaScript
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
const particles = []
const particle = class {
constructor({x = 0, y = 0, vx = 0, vy = 0}) {
this.x = x
this.y = y
this.vx = vx
this.vy = vy
this.ax = 0
this.ay = 0
particles.push(this)
this.index = particles.length
}
calc() {
for (let i of particles.slice(this.index)) {
const dx = i.x - this.x
const dy = i.y - this.y
let r = Math.sqrt(dx * dx + dy * dy)
if (Math.abs(r) < 1) r = r / Math.abs(r)
const ra = (1 / Math.pow(r, 3) - 2 / Math.pow(r, 4))
this.ax += dx * ra
this.ay += dy * ra
i.ax -= this.ax
i.ay -= this.ay
}
// calculate about walls
const ldx = this.x
const ldy = 0
let lr = Math.sqrt(ldx * ldx + ldy * ldy)
if (Math.abs(lr) < 1) lr = lr / Math.abs(lr)
const lra = (1 / Math.pow(lr, 3) - 2 / Math.pow(lr, 4))
const rdx = 100 - this.x
const rdy = 0
let rr = Math.sqrt(rdx * rdx + rdy * rdy)
if (Math.abs(rr) < 1) rr = rr / Math.abs(rr)
const rra = (1 / Math.pow(rr, 3) - 2 / Math.pow(rr, 4))
const bdx = 0
const bdy = 250 - this.y
let br = Math.sqrt(bdx * bdx + bdy * bdy)
if (Math.abs(br) < 1) br = br / Math.abs(br)
const bra = (1 / Math.pow(br, 3) - 2 / Math.pow(br, 4))
this.ax += ldx * lra + rdx * rra + bdx * bra
this.ay += ldy * lra + rdy * rra + bdy * bra
this.x += this.ax / 2 + this.vx
this.y += this.ay / 2 + this.vy
this.vx += this.ax
this.vy += this.ay + 0.6
this.ax = 0
this.ay = 0
// this.vx *= Math.abs(500 - Math.abs(this.vx)) / 500
// this.vy *= Math.abs(500 - Math.abs(this.vy)) / 500
if (this.x > 100) {
this.x = 200 - this.x
this.vx = -this.vx * 0.6
}
if (this.x < 0) {
this.x = - this.x
this.vx = -this.vx * 0.6
}
if (this.y > 250) {
this.y = 500 - this.y
this.vy = -this.vy * 0.6
}
...