Search code examples
javascriptsvgcanvaspngimage-conversion

Javascript canvas.toDataUrl() not encoding properly in Firefox


I'm trying to take an SVG and convert it to an image/png data url.

In Chrome 68 it works perfectly, but in Firefox 61 it renders an empty image with the URL of:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAFACAYAAADNkKWqAAABpElEQVR4nO3BAQ0AAADCoPdPbQ8HFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCnAUGaAAH3lkeeAAAAAElFTkSuQmCC

My code to convert and SVG is found below. You may recognize, it's pretty much just copy/paste from different sites/questions where others were trying to accomplish this.

function importSVG(sourceSVG, height = null, width = null) {

return new Promise(function (resolve, reject) {

    try {
        // https://developer.mozilla.org/en/XMLSerializer
        const svgString = (new XMLSerializer()).serializeToString(sourceSVG);
        let svgSize = sourceSVG.getBoundingClientRect();

        let canvas = document.getElementById('compass-canvas');
        canvas.width = width ? width : svgSize.width;
        canvas.height = height ? height : svgSize.height;

        let ctx = canvas.getContext('2d');
        let img = document.createElement('img');
        let svg = new Blob([svgString], {type: 'image/svg+xml;charset=utf-8'});
        let DOMURL = self.URL || self.webkitURL || self;
        let url = DOMURL.createObjectURL(svg);

        img.onload = (function () {
            ctx.drawImage(img, 0, 0);
            let png = canvas.toDataURL();
            DOMURL.revokeObjectURL(png);

            resolve({image: png});
        });

        img.onerror =
            img.onabort = function (e) {
                console.error('generateIcon : error on image', e);
            };

        img.src = url;
    }
    catch (e) {
        console.log('reject', e);
        reject(e);
    }

});
}

Is this an issue that others have encountered in the newer Firefox, or am I missing something that should be pretty obvious?


Solution

  • as @HelderSepu said, there is nothing wrong with my code. The issue with firefox is I did not have a height/width set on my SVG element.

    I found the solution in @Kaiido's answer here

    So, I set the height and width attribute before using the XMLSerializer:

    sourceSVG.setAttribute('width', 500);
    sourceSVG.setAttribute('height', 500);