Здравствуйте, помогите пожалуйста, как привести в движение мячик по клику?

let ctx = canvas.getContext("2d");
let ballRadius = 30;
let ball = new Path2D();
let x = canvas.width/2;
let y = canvas.height-30;
let dx = 0;
let dy = 0;
figures = [ball];
canvas.onclick = e => {
  figures.forEach(f => {
    if(ctx.isPointInPath(f, e.offsetX, e.offsetY)){
      if(f.id == 2) {
                console.log('click to ball')
      }
    }
  })
}

function drawBall() {
    ball.arc(x, y, ballRadius, 0, Math.PI*2);
    ctx.strokeStyle = "#FF0000";
    ctx.fillStyle = "#FF0000";
    ball.id = 2;
        ctx.fill(ball);
        ctx.stroke(ball);
}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBall();
    
    if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
        dx = -dx;
    } if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
        dy = -dy;
    }
    
    x += dx;
    y += dy;
}

setInterval(draw, 10);```

``` canvas { background: #fff; } ```
``` <canvas id="myCanvas" width="480" height="320"></canvas> ```

Ответы (1 шт):

Автор решения: Leonid

Немного упростил код. Потому как там и без обработки клика не все в порядке.

let canvas = document.getElementById('myCanvas');
let ctx = canvas.getContext("2d");
let ballRadius = 30;
let ball;
let x = canvas.width/2;
let y = canvas.height-30;
let dx = 1; // Здесь указывается по сути скорость движения
let dy = 1; // 0 будет означать, что скорость нулевая.
ctx.fillStyle = "#FF0000";

canvas.onclick = e => {
    if(ctx.isPointInPath(ball, e.offsetX, e.offsetY)){
            requestAnimationFrame(draw); // Здесь можно просто draw()
    }
}

function drawBall() {
    ball = new Path2D();
    ball.arc(x, y, ballRadius, 0, Math.PI*2);
    ctx.fill(ball);
}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBall();
    
    if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
        dx = -dx;
    } if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
        dy = -dy;
    }
    
    x += dx;
    y += dy;
    
    requestAnimationFrame(draw); // Рекурсивный вызов функции draw по готовности браузером рендерить новый кадр
}

drawBall(); // Изначально отрисовываем сам круг, а только при клике - вызываем анимацию
  
<canvas id="myCanvas" width="600" height="190"></canvas>

Заметьте, что при повторном клике функция вызывается еще раз, она создает новый рекурсивный "поток", что "ускоряет" движение шарика. Поэтому лучше фиксировать флагом начало анимации и при наличии флага не вызывать draw повторно (если это вообще надо). RequestAnimationFrame возвращает requestID, которое можно передать методу cancelAnimationFrame() для остановки анимации.

→ Ссылка