How to draw SVG image on canvas with Konva

How to show SVG image on canvas?

Long time ago browsers were not able to draw *.svg images on canvas. But right now the situations is better.

So if you want to show a vector image with Konva you have several ways for that:

  1. Use Konva.Path. That way is good for simple path shapes. If you have large svg with many paths you can split it manually into several Konva.Path shapes.

  2. Use Konva.Image shape with svg image

Konva.Image.fromURL('/image.svg', (image) => {
layer.add(image);
layer.draw();
})

That way works ok for many cases. But it is not fully cross capable. At the time of writing this post some SVG are not visible in the Firefox browser (the is a workaround for that case).

  1. Use external library to draw svg into <canvas> element. And then use that canvas for Konva.Image.

We can use canvg to parse SVG and draw it into <canvas>.

I was using that method in a large production app to have a predictable SVG result on the canvas.

Here is the demo that shows drawing natively and with a library.

Konva GIF demoview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/[email protected]/konva.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/canvg/dist/browser/canvg.min.js"></script>
<meta charset="utf-8" />
<title>Konva SVG Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
</style>
</head>

<body>
<div id="container"></div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});

var layer = new Konva.Layer();
stage.add(layer);

var SOURCE = '/assets/tiger.svg';
// try to draw SVG natively
Konva.Image.fromURL(SOURCE, imageNode => {
layer.add(imageNode);
imageNode.setAttrs({
width: 150,
height: 150
});
layer.batchDraw();
});

// draw svg with external library
var canvas = document.createElement('canvas');
canvg(canvas, SOURCE, {
renderCallback: function() {
var image = new Konva.Image({
image: canvas,
x: 200,
width: 150,
height: 150
});
layer.add(image);
layer.batchDraw();
}
});
</script>
</body>
</html>
Next