Home > Back-end >  Javascript async await with canvas
Javascript async await with canvas

Time:02-03

I'm creating a canvas with mutiple images, but they need to be added in a certain order, for example sky first, the clouds, moutains, hills, grass, road, then car.

When I add the images they load at different times so can't get the order right. My plan was to use a async function so that they wait for each image to finish. But it's not working. Code below.

function addImageProcess(src){
  return new Promise((resolve, reject) => {
    let img = new Image()
    img.onload = () => resolve(img)
    img.onerror = reject
    img.src = src
  })
}

addImageProcess('sky.png').then(img => { canvas2.getContext('2d').drawImage(img, 0, 0) });
addImageProcess('clouds.png').then(img => { canvas2.getContext('2d').drawImage(img, 0, 0) });
addImageProcess('moutains.png').then(img => { canvas2.getContext('2d').drawImage(img, 0, 0) });
addImageProcess('hills.png').then(img => { canvas2.getContext('2d').drawImage(img, 0, 0) });
addImageProcess('grass.png').then(img => { canvas2.getContext('2d').drawImage(img, 0, 0) });
addImageProcess('road.png').then(img => { canvas2.getContext('2d').drawImage(img, 0, 0) });
addImageProcess('car.png').then(img => { canvas2.getContext('2d').drawImage(img, 0, 0) });

Have been pulling my hair out for hours trying to get this to work, hopefully someone can help!

CodePudding user response:

Try using Promise.all:

Promise.all(
    [
        'sky.png', 'clouds.png', 'mountains.png', 'hills.png', 'grass.png', 'road.png', 'car.png'
    ].map(
        addImageProcess
    )
).then(
    (allImages)=>allImages.map(
        img=>canvas2.getContext('2d').drawImage(img, 0, 0)
    )
)

Promise.all can be used to wait for all promises to finish before moving on to the next phase.

If you want to do something different with each image you can do something like this:

Promise.all(
    [
        'sky.png', 'clouds.png', 'mountains.png', 'hills.png', 'grass.png', 'road.png', 'car.png'
    ].map(
        addImageProcess
    )
).then(
    ([sky, clouds, mountains, hills, grass, road, car])=>{
         const context = canvas2.getContext('2d');
         
         context.drawImage(clounds, 5, 2);
         context.drawImage(hills, 20, 50);
    }
)
  • Related