0

I am currently working on a web-application. As part of it I am creating SVG-images internally. When it comes to rendering, I used the approach provided in this question in order to convert the svg to a bitmap and displaying it on a canvas: https://stackoverflow.com/a/23667012/5767042

Most of the times this works fine, however sometimes it does not render the SVG image. Using the chrome DevTools, I was able to confirm that the object being passed to drawImage() (in the example below this would be imageBitmap) is the same in every call, however sometimes it gets rendered and sometimes it does not. I don't understand this behaviour at all.

var svgStr = "<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"100\" height=\"100\" shape-rendering=\"crispEdges\" stroke-linecap=\"square\"><line x1=\"0\" y1=\"0\" x2=\"50\" y2=\"50\" stroke=\"rgb(0,0,0)\" stroke-width=\"4\"\/><line x1=\"0\" y1=\"50\" x2=\"50\" y2=\"0\" stroke=\"rgb(0,0,0)\" stroke-width=\"4\"\/><\/svg>";

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var imageBitmap = new Image();
imageBitmap.src = 'data:image/svg+xml;base64,'+window.btoa(svgStr);
console.log('drawing bitmap');

ctx.drawImage(imageBitmap, 0, 0);
<canvas id="myCanvas" width="200" height="100"></canvas>

Am I using drawImage() in a wrong way? I had the same behaviour in Firefox, Edge doesn't work at all. I also tested it on three different machines, no difference.

Sebastian Speitel
  • 7,166
  • 2
  • 19
  • 38

1 Answers1

0

You need to wait until the image is finished loading. For that you can use the .onload handler of the image, which is called when it's loaded.

var svgStr = "<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"100\" height=\"100\" shape-rendering=\"crispEdges\" stroke-linecap=\"square\"><line x1=\"0\" y1=\"0\" x2=\"50\" y2=\"50\" stroke=\"rgb(0,0,0)\" stroke-width=\"4\"\/><line x1=\"0\" y1=\"50\" x2=\"50\" y2=\"0\" stroke=\"rgb(0,0,0)\" stroke-width=\"4\"\/><\/svg>";

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var imageBitmap = new Image();
imageBitmap.src = 'data:image/svg+xml;base64,' + window.btoa(svgStr);

function drawBitmap() {
  console.log('drawing bitmap');

  ctx.drawImage(imageBitmap, 0, 0);
}

imageBitmap.onload = drawBitmap;
<canvas id="myCanvas" width="200" height="100"></canvas>
Sebastian Speitel
  • 7,166
  • 2
  • 19
  • 38
  • That was it. I ruled this out because I created the SVG and bitmap programatically and everything is executed sequentially. Also the DevTools showed the correct information about the bitmap object. Do you know why it still happens? – Jason Durham Jun 20 '18 at 18:50
  • The parser probably still takes time to create an internal copy of the image in the format it will be rendered – Sebastian Speitel Jun 20 '18 at 19:00