window.requestAnimationFrame()
actually invokes the function passed by parameter every 16.67 milliseconds (that is, 60 times per second). The responsibility of the function passed as a parameter to window.requestAnimationFrame()
is to draw what you need to draw, either using <canvas>
, <img>
or <div>
with background-image
.
Let's imagine that imagemA
and imagemB
are ImageBitmaps
with the horizontally arranged side-by-side frames that you draw in a <canvas>
using renderingContext.drawImage()
. We will then have something similar to:
var canvas = document.getElementById("meuCanvas"),
ctx = canvas.getContext("2d"),
imagemA = new Image(),
imagemB = new Image(),
num_ticks = 0,
largura_A, altura_A, frames_A, x_A, y_A,
largura_B, altura_B, frames_B, x_B, y_B,
bmpA, bmpB;
// carregar as imagens
imagemA.src = "path/to/imageA";
imagemB.src = "path/to/imageB";
// quando as imagens terminarem de carregar...
Promise.all([
new Promise(function (resolve, reject) {
imagemA.onload = function () { resolve(this); }
}),
new Promise(function (resolve, reject) {
imagemB.onload = function () { resolve(this); }
})
]).then(function (imgA, imgB) {
bmpA = createImageBitmap(imgA);
bmpB = createImageBitmap(imgB);
desenhar_frame(); // inicia a animação
});
function desenhar_frame() {
// imagemA tem largura_A por altura_A pixels e frames_A frames, sendo desenhado em (x_A, y_A);
// imagemB tem largura_B por altura_B pixels e frames_B frames, sendo desenhado em (x_B, y_B).
// o frame de A sempre avança
ctx.drawImage(
bmpA,
x_A, y_A,
largura_A, altura_A,
x_A * (num_ticks % frames_A), 0,
largura_A, altura_A
);
// B tem que ser desenhado toda vez, mas o frame só avança chamada sim, chamada não
ctx.drawImage(
bmpB,
x_B, y_B,
largura_B, altura_B,
x_B * (num_ticks % (2 *frames_B)), 0,
largura_B, altura_B
);
// avança o contador de frames e registra a função para
// se chamar de novo daqui a 1/60 segundos
num_ticks ++;
requestAnimationFrame(desenhar_frame);
};