Рисовать изображения на холсте с разной скоростью

1

Учитывая два разных изображения (скажем, image A и image B), скажем, я хочу нарисовать image A на холсте со скоростью около 60 FPS, и я хочу нарисовать image B примерно на 30 FPS.

Мой вопрос: с помощью requestAnimationFrame лучший способ сделать это? Должен ли я создать 2 полотна?

Теги:
frame-rate
html5-canvas
requestanimationframe

2 ответа

2
Лучший ответ

Обратный вызов requestAnimationFrame получает в качестве первого аргумента requestAnimationFrame метку. Используйте эту метку времени, чтобы вычислить время, прошедшее между последним и текущим выполнением обратного вызова, и провести в соответствии с этим.

Вот простой пример, демонстрирующий вышеприведенный принцип:

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>
0

Вы также можете использовать 2 холста, но заставляйте их действовать как слои, то есть "складывать их", используя абсолютное позиционирование.

Здесь есть полезная статья, написанная Джеймсом Листеном

Я начал скрипку; это потребует немного настройки в соответствии с вашими потребностями (код такой же, как фрагмент)

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>
  • 0
    Джеймс использует setInterval при рисовании своих слоев. Он не используется в приведенном выше коде.
  • 0
    Да, мой план состоял в том, чтобы наложить два холста, но небольшая настройка кода @le_m может сделать это

Ещё вопросы

Сообщество Overcoder
Наверх
Меню