DJEveridge
DJEveridge

Reputation: 35

moving a circle with HTML canvas and vanilla JavaScript

I am practicing with HTML Canvas and JavaScript, and I am trying to move a circle. I have everything set up to move the circle and change the size with button on the scree. However, for example, if I click the left button and then click the right button, the circle will just stop because the x position is just increasing by the same x value that it was decreasing to go left. How can I make it so that if the circle is moving left at 2 pixels every 10 milliseconds, I can click the move right button, and it will move right at 2 pixels every 10 milliseconds instead of just stopping.

const canvas = document.getElementById("canvas1");
const ctx = canvas.getContext('2d',);
const posUp = document.getElementById("posUp");
const posDown = document.getElementById("posDown");
const posRight = document.getElementById("posRight");
const posLeft = document.getElementById("posLeft");
const radUp = document.getElementById("radUp");
const radDown = document.getElementById("radDown");
const dx = 2;
const dy= 2;
let size = 0; 
let PI = Math.PI;
let posX = window.innerWidth/2;
let posY = window.innerHeight/2;
let angle = 0;
let radius = 50;
let posXInt, posYInt;



canvas.width = window.innerWidth;
canvas.height = window.innerHeight;


const rrgb = `rgb(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)})`
const strokeRRGB = `rgb(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)})`


function posUpFunc() {    
    posY-= dy;
}

function posRightFunc() {
    posX += dx;
}

function posDownFunc() {
    posY+= dy;
}

function posLeftFunc() {
    posX-= dx;
}

function radUpFunc() {
    radius++;
}

function radDownFunc() {
    radius--;
    if(radius <= 0) {
        radius = 0;
    }
}

posUp.onclick = () => {
    console.log(posY)
clearInterval(posYInt);
    setInterval(posUpFunc, 10);
}

posRight.onclick = () => {
    console.log(posY)    
 clearInterval(posXInt);

    setInterval(posRightFunc, 10);

}

posDown.onclick = () => {
    console.log(posY)
clearInterval(posYInt);

    setInterval(posDownFunc, 10);
}

posLeft.onclick = () => {
    console.log(posY)
clearInterval(posXInt);

    setInterval(posLeftFunc, 10);
}

radUp.onclick = () => {
    let count = 0;
    let interval = setInterval(() => {
      if (count > 20) clearInterval(interval);   //chnage 20 to amount of radius by which you want to increase it
      radUpFunc();
      count++;
    }, 10);
}

radDown.onclick = () => {
    let count = 0;
    let interval = setInterval(() => {
      if (count > 20) clearInterval(interval);   //chnage 20 to amount of radius by which you want to increase it
      radDownFunc();
      count++;
    }, 10);
}


function draw() {
    ctx.fillStyle = rrgb;
    ctx.strokeStyle = strokeRRGB;
    ctx.lineWidth = radius/18;
    ctx.clearRect(0,0,window.innerWidth,window.innerHeight)
    ctx.beginPath();
    ctx.arc(posX, posY, radius, 0, PI * 2);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
 
}    



setInterval(draw, 10)
body {
    overflow: hidden;
}


#canvas1 {
    position: absolute;
    border: 2px solid black;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;

}

button {
    height: 2.5%;
    width: 5%;
    position: absolute;
    cursor: pointer;
    z-index: 100;
}

button:hover {
    border: 1px solid black;
}

#posUp {
    left: 5%;
}

#posRight {
left: 10%;
top: 6.5%;
}

#posDown {
left: 5%;
top: 10%;
}

#posLeft {
left: 0%;
top: 6.5%;

}

#radUp {
left: 50.5%;
}

#radDown {
left: 50.5%;
top: 10%;
}

#circle-direction {
position: relative;
top: 5%;
left: 3%;
width: fit-content;
height: fit-content;
z-index: 100;

}

#circle-size {
    position: absolute;
    top: 2.5%;
    left: 50%;
    width: fit-content;
    height: fit-content;
    z-index: 100;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <script src="aestheticPasswordStrengthMeter.js" defer></script>
<link rel="stylesheet" href="aestheticPasswordStrengthMeter.css">  
  <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="circle-direction">Change circle direction.</div>
    <div id="circle-size"> Change circle size.</div>
    <button id="posUp">⇑</button>
    <button id="posRight">⇒</button>
    <button id="posDown">⇓</button>
    <button id="posLeft">⇐</button>
    <button id="radUp">⇑</button>
    <button id="radDown">⇓</button>
    <canvas id="canvas1"></canvas>
</body>
</html>

Upvotes: 1

Views: 252

Answers (1)

Ma3x
Ma3x

Reputation: 6549

You can do what you want. You have to save the values (the IDs) you get from setInterval calls in order to clear the intervals when you need to. In your code example you are already calling clearInterval but you are passing an undefined value as the parameter. You have to pass the value that you received from a setInterval (or setTimeout) call.

Like this

let posXInt, posYInt;

posUp.onclick = () => {
    clearInterval(posYInt);
    posYInt = setInterval(posUpFunc, 10);
}

posDown.onclick = () => {
    clearInterval(posYInt);
    posYInt = setInterval(posDownFunc, 10);
}

posRight.onclick = () => {
    clearInterval(posXInt);
    posXInt = setInterval(posRightFunc, 10);
}

posLeft.onclick = () => {
    clearInterval(posXInt);
    posXInt = setInterval(posLeftFunc, 10);
}

But if you do that, you will then also need a button to stop the movement of the circle.

// add this button to you layout etc...
stopButton.onclick = () => {
    clearInterval(posXInt);
    clearInterval(posYInt);
}

Upvotes: 2

Related Questions