I’m creating a code where 3 balls will bounce when a button is clicked. I have a code I found in the internet and added the start button but clicking it multiple times speed up the balls. Also, I tried adding a reset button that will clear out the canvas but can’t make it work. Sharing both the HTML and JS code.
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = 1000;
const height = canvas.height = 500;
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, width, height);
function random(min, max) {
const num = Math.floor(Math.random() * (max - min + 1)) + min;
return num;
}
function Ball(x, y, velX, velY, color, size) {
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
this.color = color;
this.size = size;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
ctx.fill();
}
Ball.prototype.update = function() {
if ((this.x + this.size) >= width) {
this.velX = -(this.velX);
}
if ((this.x - this.size) <= 0) {
this.velX = -(this.velX);
}
if ((this.y + this.size) >= height) {
this.velY = -(this.velY);
}
if ((this.y - this.size) <= 0) {
this.velY = -(this.velY);
}
this.x += this.velX;
this.y += this.velY;
}
let balls = [];
function loop() {
while (balls.length < 3) {
let size = 35;
let ball = new Ball(
random(0 + size, width - size), random(0 + size, height - size), 5, 5, 'yellow', size);
balls.push(ball);
}
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, width, height);
for (let i = 0; i < balls.length; i++) {
balls[i].draw();
balls[i].update();
}
requestAnimationFrame(loop);
}
document.getElementById('Begin').addEventListener('click',loop);<input type='button' id='Begin' value='start'> <canvas id='myCanvas'></canvas>
Advertisement
Answer
You need to store the requestAnimationFrame in a var and use cancelAnimationFrame to stop
I added a div to hold the buttons and now delegate from that div so only one event handler is needed.
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = 1000;
const height = canvas.height = 500;
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, width, height);
let rq; // this we can use to request and cancel
function random(min, max) {
const num = Math.floor(Math.random() * (max - min + 1)) + min;
return num;
}
function Ball(x, y, velX, velY, color, size) {
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
this.color = color;
this.size = size;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
ctx.fill();
}
Ball.prototype.update = function() {
if ((this.x + this.size) >= width) {
this.velX = -(this.velX);
}
if ((this.x - this.size) <= 0) {
this.velX = -(this.velX);
}
if ((this.y + this.size) >= height) {
this.velY = -(this.velY);
}
if ((this.y - this.size) <= 0) {
this.velY = -(this.velY);
}
this.x += this.velX;
this.y += this.velY;
}
let balls = [];
function loop() {
while (balls.length < 3) {
let size = 35;
let ball = new Ball(
random(0 + size, width - size), random(0 + size, height - size), 5, 5, 'yellow', size);
balls.push(ball);
}
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, width, height);
for (let i = 0; i < balls.length; i++) {
balls[i].draw();
balls[i].update();
}
rq = requestAnimationFrame(loop);
}
document.getElementById('butDiv').addEventListener('click', function(e) {
const tgt = e.target;
if (tgt.id === "Begin") {
if (tgt.value === "start") {
loop()
tgt.value = "stop";
document.getElementById("resetCanvas").classList.add("hide");
} else {
cancelAnimationFrame(rq)
this.value = "start";
document.getElementById("resetCanvas").classList.remove("hide");
}
} else if (tgt.id === "resetCanvas") {
cancelAnimationFrame(rq)
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, width, height);
document.getElementById("Begin").value="start";
tgt.classList.add("hide");
}
}).hide {
display: none;
}<div id="butDiv"> <input type='button' id='Begin' value='start'> <input type='button' class="hide" id='resetCanvas' value='reset'> </div> <canvas id='myCanvas'></canvas>