Reputation: 375
Given two different images (say image A
and image B
), let's say I want to draw image A
on a canvas at a rate of about 60 FPS and I want to draw image B
at about 30 FPS.
My question is, using requestAnimationFrame what is the best way to do this? Should I create 2 canvases?
Upvotes: 2
Views: 1386
Reputation: 28553
You could also use 2 canvases but make them act as layers, i.e. "stack them" using absolute positioning.
There is a helpful article here, written by James Litten
I started a fiddle; it would need a bit of tweaking to suit your needs (code same as snippet)
var layer1 = document.getElementById("layer1");
var layer2 = document.getElementById("layer2");
var ctx1 = layer1.getContext("2d");
var ctx2 = layer2.getContext("2d");
var img1 = loadImage('http://www.rachelgallen.com/images/purpleflowers.jpg', main);
var img2 = loadImage('http://www.rachelgallen.com/images/yellowflowers.jpg', main);
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if (imagesLoaded == 2) {
// set alpha for individual images as desired
ctx1.globalAlpha = 0.8;
ctx2.globalAlpha = 0.5;
drawAll();
}
}
function draw1() {
frameRate = 30;
ctx1.clearRect(0, 0, 250, 150);
ctx1.beginPath();
ctx1.rect(0, 0, 250, 150);
ctx1.drawImage(img1, 0, 0); //draw 1st image
ctx1.closePath();
}
function draw2() {
frameRate = 60;
ctx2.clearRect(0, 0, 250, 150);
ctx2.beginPath();
ctx2.rect(0, 0, 250, 150);
ctx2.drawImage(img2, 0, 0); //draw 2nd image
ctx2.closePath();
}
function drawAll() {
draw1();
draw2();
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
return img;
}
#layer1,
#layer2 {
position: absolute;
top: 0;
left: 0;
}
<canvas id="layer1">
</canvas>
<canvas id="layer2">
</canvas>
Upvotes: 0
Reputation: 20228
The callback of requestAnimationFrame
receives a timestamp as its first argument. Use that timestamp to compute the time that passed between the last and the current execution of the callback and draw according to that.
Here is a simple example demonstrating the above principle:
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let last100 = 0;
let last500 = 0;
function frame(time) {
ctx.fillStyle = 'rgb(' + Math.random() * 255 + ', 0, 0)';
// 10 frames per second (1000/10 = 100):
if (time > last100 + 100) {
ctx.fillRect(0, 0, 100, 100);
last100 = time;
}
// 2 frames per second (1000/2 = 500):
if (time > last500 + 500) {
ctx.fillRect(200, 0, 100, 100);
last500 = time;
}
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
<canvas id="canvas"></canvas>
Upvotes: 4