htmlvue.jscanvasdrawimage

HTML 5 wait for drawImage to finish in a Vue SPA


I have been trying to debug something for a week and I now suspect the problem is that the drawImage function does not have time to finish. I have a for loop that composes a canvas element by stitching together two different canvas elements and then add that composedCanvas as a frame to a GIF.js object. The problem I keep running into is that the bottom stitched canvas does not appear or partially appears (the picture below started to draw but did not finish) in my output GIF file. My question is how do I ensure synchronous execution of drawImage in the context of a Vue SPA method. I have experimented with Promise, but I have not gotten it to work. Can anyone explain and help me with this, please?

EDIT : I have tried wrapping my drawImage in a promise and await but it raised type errors.

enter image description here


Solution

  • I managed to get it working by properly wrapping the drawImage step in a separate method and inside a promise the proper way. See the code below for an example of two methods that were the culprits but are now fixed.

    async composeCanvas( gif , timeStep , visibleLayers , delayInput) {
        const mapCnv = this.getMapCanvas();
        await this.updateInfoCanvas( timeStep )
        const numberVisibleLayers = visibleLayers.length;
        const composedCnv = await this.stitchCanvases( mapCnv , numberVisibleLayers );
        gif.addFrame(composedCnv, {copy:false, delay: delayInput});
    },
    async stitchCanvases( mapCanvas , numberVisibleLayers ) {
        return new Promise(( resolve ) => {
            var composedCnv = document.createElement('canvas');
            var ctx = composedCnv.getContext('2d');
            var ctx_w = mapCanvas.width;
            var ctx_h = mapCanvas.height + ((numberVisibleLayers - 1) * 30) + 40;
            
            composedCnv.width = ctx_w;
            composedCnv.height = ctx_h;
    
            [
                {
                    cnv: mapCanvas,
                    y: 0
                },
                {
                    cnv: this.infoCanvas,
                    y: mapCanvas.height
                }
            ].forEach( ( n ) => {
                ctx.beginPath();
                ctx.drawImage(n.cnv, 0, n.y, ctx_w, n.cnv.height);
            });
    
            resolve(composedCnv)
        })
    }