Как анимировать canvas?

104
05 декабря 2021, 11:40

По нажатию на кнопку квадрат изменяет позицию. Как сделать это перемещение плавным? Может как то с помощью requestAnimationFrame() или setInterval()?
Сам код:

let canvas = document.getElementById('canvas'), 
    ctx = canvas.getContext('2d'), 
    w = canvas.width = 200, 
    h = canvas.height = 200, 
    opts = { 
        w: 80, 
        h: 80, 
        x: 0, 
        y: 0 
    }; 
 
ctx.fillStyle = 'blue'; 
ctx.fillRect(opts.x, opts.y, opts.w, opts.h); 
 
document.onkeydown = control; 
 
function control() { 
    let speed = 20; 
    ctx.clearRect(opts.x, opts.y, opts.w, opts.h) 
    if(event.keyCode == 38) {   // up 
        opts.y -= speed; 
    } 
    if(event.keyCode == 40) {   // down 
        opts.y += speed; 
    } 
    if(event.keyCode == 37) {   // left 
        opts.x -= speed; 
    } 
    if(event.keyCode == 39) {   // down 
        opts.x += speed; 
    } 
    ctx.fillRect(opts.x, opts.y, opts.w, opts.h) 
}
#canvas { 
    border: 1px solid; 
}
<canvas id="canvas"></canvas>

Answer 1

Можно управлять скоростью по нажатиям и отпусканиям клавиш и каждый кадр менять позицию на значение скорости, как-то так:

let canvas = document.getElementById('canvas'), 
    ctx = canvas.getContext('2d'), 
    w = canvas.width = 550, 
    h = canvas.height = 175, 
    speed = {x: 0, y: 0}, 
    time = 0, 
    opts = {w: 80, h: 80, x: 0, y: 0}; 
 
ctx.fillStyle = 'blue'; 
ctx.fillRect(opts.x, opts.y, opts.w, opts.h); 
 
document.onkeydown = control.bind(0, 1); 
document.onkeyup = control.bind(0, 0); 
 
function control(v) { 
    if (event.keyCode == 38) speed.y = -v; // up 
    if (event.keyCode == 40) speed.y =  v; // down 
    if (event.keyCode == 37) speed.x = -v; // left 
    if (event.keyCode == 39) speed.x =  v; // down   
} 
 
requestAnimationFrame(draw) 
 
function draw (t) { 
  requestAnimationFrame(draw) 
  let dt = t - time 
  opts.x += speed.x * dt/10; 
  opts.y += speed.y * dt/10; 
  ctx.clearRect(0, 0, w, h); 
  ctx.fillRect(opts.x, opts.y, opts.w, opts.h); 
  time = t; 
}
#canvas { 
    border: 1px solid; 
}
<canvas id="canvas"></canvas>

READ ALSO
Как осуществить циклический сдвиг?

Как осуществить циклический сдвиг?

Задано 4 байтовое число, с 10 по 4 биты сдвинуть влево на 3 разряда

163
Перегрузка функций по имени параметра

Перегрузка функций по имени параметра

Такой вопрос, (я только учусь, так что не бейте) есть функция, которая удаляет элемент из массива:

98
16-тиричное считывание из файла C++

16-тиричное считывание из файла C++

Излазил вдоль и поперек форум(скорее всего чего-то не заметил)

79