Учитывая два разных изображения (скажем, image A
и image B
), скажем, я хочу нарисовать image A
на холсте со скоростью около 60 FPS, и я хочу нарисовать image B
примерно на 30 FPS.
Мой вопрос: с помощью requestAnimationFrame лучший способ сделать это? Должен ли я создать 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>
Вы также можете использовать 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>