Img.onload not firing when dynamically setting src

2019-05-18 06:21发布

I am having trouble getting the onLoad handler to fire when the src of imgGraph is loaded with a generated dataURI. The dataURI is generated from a d3.js visualization (svg) using canvas.

var canvas = document.getElementById(visual + '-canvas');
if(visual == "graph"){
     console.log('graph logic n stuff')
     canvas.width = 558;
     canvas.height = 558;
     var graph = d3.select('#graph-svg').node();
     var svg_xml = (new XMLSerializer()).serializeToString(graph);
     var imgGraph = new Image();
     var context = canvas.getContext('2d');
     var imageData;
     imgGraph.onload = function(){
         console.log('img loaded')
         context.drawImage(imgGraph, 0, 0);
         imageData = getImgData(canvas);
         console.log(imageData)
         def.resolve(imageData)
     }
     console.log('setting src')
     imgGraph.src = "data:image/svg+xml;base64,"+btoa(svg_xml);
}

The img src is being set, but the img.onload is never fired. When logging and surfing to the datauri, the image is being displayed however. Other images seem to fire the onload event correctly.

DataURI - PasteBin

2条回答
【Aperson】
2楼-- · 2019-05-18 07:02

Try:

imgGraph.complete = function(){

查看更多
放我归山
3楼-- · 2019-05-18 07:03

Don't base64 encode your svg.
Instead one should prefer an percent encoded version, or for huge svg, a blobURI :

img.src = 'data:image/svg+xml;charset=utf8,' + encodeURIComponent(yourSVGMarkup);

or

img.src = URL.createObjectURL(
  new Blob([yourSVGMarkup], {
    type: 'image/svg+xml;charset=utf8'
    })
  );

JSfiddle to demonstrate the difference.

But you should note that SVGs loaded inside an <img> element can't load any external resources. So you'll have to base64 encode all the images linked in your svg prior to extract the markup if you want to draw them on your canvas too.
When this will be done, your svg markup will indeed be long, and maybe too long for a dataURI version.

That's when the blobURI is useful.

PS: if you need help for appending your raster images inside your svg, check this Q/A

查看更多
登录 后发表回答