Firefox error rendering an SVG image to HTML5 canvas with drawImage

前端 未结 3 1221
失恋的感觉
失恋的感觉 2020-11-28 16:27

I am trying to convert an external svg icon to a base64 png using a canvas. It is working in all browsers except Firefox, which throws an error \"NS_ERROR_NOT_AVAILABLE\".

3条回答
  •  半阙折子戏
    2020-11-28 17:07

    This isn't the most robust solution, but this hack worked for our purposes. Extract viewBox data and use these dimensions for the width/height attributes.

    This only works if the first viewBox encountered has a size that accurately can represent the size of the SVG document, which will not be true for all cases.

       // @svgDoc is some SVG document.
       let svgSize = getSvgViewBox(svgDoc);
    
       // No SVG size?
       if (!svgSize.width || !svgSize.height) {
          console.log('Image is missing width or height');
    
       // Have size, resolve with new SVG image data.
       } else {
          // Rewrite SVG doc
          let unit = 'px';
          $('svg', svgDoc).attr('width', svgSize.width + unit);
          $('svg', svgDoc).attr('height', svgSize.height + unit);
    
          // Get data URL for new SVG.
          let svgDataUrl = svgDocToDataURL(svgDoc);
       }
    
    
    function getSvgViewBox(svgDoc) {
       if (svgDoc) {
          // Get viewBox from SVG doc.
          let viewBox = $(svgDoc).find('svg').prop('viewBox').baseVal;
    
          // Have viewBox?
          if (viewBox) {
             return {
                width: viewBox.width,
                height: viewBox.height
             }
          }
       }
    
       // If here, no viewBox found so return null case.
       return {
          width: null,
          height: null
       }
    }
    
    function svgDocToDataURL(svgDoc, base64) {
       // Set SVG prefix.
       const svgPrefix = "data:image/svg+xml;";
    
       // Serialize SVG doc.
       var svgData = new XMLSerializer().serializeToString(svgDoc);
    
       // Base64? Return Base64-encoding for data URL.
       if (base64) {
          var base64Data = btoa(svgData);
          return svgPrefix + "base64," + base64Data;
    
       // Nope, not Base64. Return URL-encoding for data URL.
       } else {
          var urlData = encodeURIComponent(svgData);
          return svgPrefix + "charset=utf8," + urlData;
       }
    }
    

提交回复
热议问题