Safirah
Safirah

Reputation: 375

Draw images on canvas at different rates

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

Answers (2)

Rachel Gallen
Rachel Gallen

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

le_m
le_m

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

Related Questions