Move several balls
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Balls move</title> <link rel="stylesheet" href="style.css"> </head>//w ww . jav a2 s . c o m <body> <canvas id="canvas" width="700" height="500"></canvas> <script> class Vector2D { constructor(x, y) { this.x = x; this.y = y; } // PUBLIC METHODS lengthSquared() { return this.x * this.x + this.y * this.y; } length() { return Math.sqrt(this.lengthSquared()); } clone() { return new Vector2D(this.x, this.y); } negate() { this.x = -this.x; this.y = -this.y; } normalize() { const length = this.length(); if (length > 0) { this.x /= length; this.y /= length; } return this.length(); } add({ x, y }) { return new Vector2D(this.x + x, this.y + y); } incrementBy({ x, y }) { this.x += x; this.y += y; } subtract({ x, y }) { return new Vector2D(this.x - x, this.y - y); } decrementBy({ x, y }) { this.x -= x; this.y -= y; } multiply(k) { return new Vector2D(k * this.x, k * this.y); } addScaled({ x, y }, k) { return new Vector2D(this.x + k * x, this.y + k * y); } scaleBy(k) { this.x *= k; this.y *= k; } dotProduct({ x, y }) { return this.x * x + this.y * y; } } // STATIC METHODS Vector2D.distance = (vec1, vec2) => (vec1.subtract(vec2)).length() Vector2D.angleBetween = (vec1, vec2) => Math.acos(vec1.dotProduct(vec2) / (vec1.length() * vec2.length())) class Ball { constructor(radius, color, mass, charge, gradient) { this.radius = 20; this.color = '#0000ff'; this.mass = 1; this.charge = 0; this.x = 0; this.y = 0; this.vx = 0; this.vy = 0; } get pos2D() { return new Vector2D(this.x, this.y); } set pos2D({ x, y }) { this.x = x; this.y = y; } get velo2D() { return new Vector2D(this.vx, this.vy); } set velo2D({ x, y }) { this.vx = x; this.vy = y; } draw(context) { context.fillStyle = this.color; context.beginPath(); context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, true); context.closePath(); context.fill(); } } const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d'); let balls; let t; let t0; let dt; let animId; const animTime = 10; // duration of animation const numBalls = 10; window.onload = init; function init() { balls = new Array(); for (let i = 0; i < numBalls; i++) { const radius = (Math.random() + 0.5) * 20; const ball = new Ball(); ball.pos2D = new Vector2D(canvas.width / 2, canvas.height / 2); ball.velo2D = new Vector2D((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 20); ball.draw(context); balls.push(ball); } t0 = new Date().getTime(); t = 0; animFrame(); } function animFrame() { animId = requestAnimationFrame(animFrame, canvas); onTimer(); } function onTimer() { const t1 = new Date().getTime(); dt = 0.001 * (t1 - t0); t0 = t1; t += dt; if (t < animTime) { move(); } else { stop(); } } function move() { context.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < numBalls; i++) { const ball = balls[i]; ball.pos2D = ball.pos2D.addScaled(ball.velo2D, dt); ball.draw(context); } } function stop() { cancelAnimationFrame(animId); } </script> </body> </html>