用 HTML canvas 和香草 JavaScript 移动一圈

moving a circle with HTML canvas and vanilla JavaScript

我正在练习HTMLCanvas和JavaScript,我正在尝试移动一个圆圈。我已设置好一切以移动圆圈并使用屏幕上的按钮更改大小。但是,例如,如果我单击左键然后单击右键,圆圈将停止,因为 x 位置只是增加了与向左减少时相同的 x 值。我怎样才能做到,如果圆圈每 10 毫秒向左移动 2 个像素,我可以单击向右移动按钮,它会每 10 毫秒向右移动 2 个像素,而不仅仅是停止。

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>

你可以做你想做的。 您必须保存从 setInterval 调用中获得的值(ID),以便在需要时清除间隔。 在您的代码示例中,您已经在调用 clearInterval 但您正在传递一个 undefined 值作为参数。您必须传递从 setInterval(或 setTimeout)调用中收到的值。

像这样

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);
}

但如果这样做,您还需要一个按钮来停止圆圈的移动。

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