我有以下JavaScript文件,其中包含一个名为menu
的函数,该函数调用draw
函数4次不同的时间以在屏幕上显示4张不同的图像。
我需要按编码顺序显示它们,但是每次刷新时,都会得到一些不同的信息。我知道这很可能是因为某些图像的加载速度比其他图像快。
我在网站上查找了其他示例,该解决方案似乎仅在首先加载所有图像时才绘制图像,但是我无法使其正常工作。
还有其他方法吗?
var cvs = document.getElementById("canvas");
var ctx = cvs.getContext("2d");
var audio = new Audio('sounds/sound.ogg');
cvs.addEventListener("click", function(){
audio.play();
});
var logoSound;
ctx.fillStyle= "#87ceeb";
ctx.fillRect(0,0,1330,800);
function draw(src, a, b) {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function() {
ctx.drawImage(img, x, y);
};
img.src = src;
}
function menu() {
draw("images/clouds.png", 0, 300);
draw("images/background.png", 0, 360);
draw("images/display.png", 410, 0);
draw("images/plank.png", 405, 300);
}
menu();
更新
async function draw(src,x,y) {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function(){
ctx.drawImage(img,x,y);
};
img.src = src;
}
// main
(async function menu (){
await draw("images/clouds.png", 0, 300);
await draw("images/background.png", 0, 360);
await draw("images/display.png", 410, 0);
await draw("images/plank.png", 405, 300);
await draw("images/info.png", 1195, 660);
}());
function cloud2(){
ctx.drawImage(cloud, speed, 0);
cvs.requestAnimationFrame(cloud);
}
menu();
答案 0 :(得分:0)
您可以使绘图函数异步。 setTimeout调用是对异步加载程序处理程序的模拟。
async function draw (msg) {
return new Promise ((resolve, reject) => {
let randomDelay = Math.floor(Math.random() * 3000);
setTimeout(() => {
resolve(msg);
}, randomDelay);
});
}
(async function (){
console.log(await draw(1));
console.log(await draw(2));
console.log(await draw(3));
console.log(await draw(4));
}());
这将保证图纸的顺序。
输出为: 1个 2 3 4
答案 1 :(得分:0)
在画布上绘制图像是同步操作,不是加载这些图像。
因此将逻辑分为1.Loading,然后2.Drawing
加载部分将仅创建需要绘制的<img>
个元素,由于Promises,操作大大简化了。
完成后,绘图部分将迭代图像并绘制它们:
const ctx = canvas.getContext('2d');
function loadImages(urls) {
return Promise.all(urls.map(loadImage));
}
function loadImage(url) {
return new Promise((res, rej) => Object.assign((new Image()), {
src: url,
onload: function(e){res(this)},
onerror: rej
}));
}
function drawImages(images) {
images.forEach((img, i) => ctx.drawImage(img, i * 50, 0));
}
async function begin() {
// build up our array of urls
const urls = Array.from({
length: 10
}, () => 'https://lorempixel.com/50/50?' + Math.random());
// load them all
const images = await loadImages(urls);
// draw them all
drawImages(images);
}
begin().catch(console.error)
<canvas id="canvas" width="500" height="50"></canvas>
请注意,这是需要外部资产时的基本操作: