Diese Variante des Punkt-Beispiels implementiert eine Punkt-Klasse (Dot), die den Zustand der Animation sowie zwei Methoden - zum Berechnen der Animation und zum Zeichnen des Punkts - enthält.
HTML<canvas id="myCanvas" width="400" height="400"></canvas>
CSS#myCanvas {
border: 1px solid;
}
JavaScriptconst canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// physics animation parameters
const dotAcceleration = -2000; // pixel per second^2
const bouncingLossFactor = 0.9; // speed loss factor when rebouncing at the bottom
const minBouncingSpeed = 25; // minimum speed stopping
const animatedDots = new Set(); // list of animated dots
let animationTime = null; // current animation time
class Dot {
constructor(x, height, size) {
this.x = x;
this.height = height;
this.speed = 0;
this.size = size;
}
animate(deltaTime) {
// update height from speed
this.height += deltaTime * this.speed;
// bounce at bottom
if (this.height <= 0) {
this.height = -this.height; // correct of negative y-positions
this.speed *= -bouncingLossFactor; // invert speed and apply loss
// stop animation when rebouncing too slowly
if (this.speed < minBouncingSpeed) {
return false;
}
}
// update speed from acceleration
this.speed += deltaTime * dotAcceleration;
// continue animation
return true;
}
draw(ctx) {
ctx.beginPath();
ctx.arc(this.x, canvas.height - this.height - this.size, this.size, 0, 360);
ctx.fill();
}
}
canvas.addEventListener('click', onClick);
function onClick(evt) {
const canvasClientRect = canvas.getBoundingClientRect();
const x = evt.clientX - canvasClientRect.x;
const y = evt.clientY - canvasClientRect.y;
// create dot
const dot = new Dot(x, canvas.height - y, 10);
// add dot to set of animated dots
animatedDots.add(dot);
// start animation on first dot
if (animatedDots.size === 1) {
animationTime = 0.001 * performance.now();
requestAnimationFrame(onAnimationFrame);
}
}
function onAnimationFrame() {
const now = 0.001 * performance.now();
const deltaTime = now - animationTime;
// clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let dot of animatedDots) {
if (dot.animate(deltaTime)) {
dot.draw(ctx);
} else {
animatedDots.delete(dot);
}
}
// continue animation
if (animatedDots.size > 0) {
animationTime = now;
requestAnimationFrame(onAnimationFrame);
}
}