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
    }
 ...