Issue
This Content is from Stack Overflow. Question asked by Ryan Peschel
According to caniuse.com, using an SVGImageElement
as the parameter to a context.drawImage
call is supported in every browser except Safari.
However, it seems like many people are using a canvas to draw SVGs in Safari?
For example, this post seems to be drawing images (granted the shadows are slightly messed up).
So, can you draw SVGs on a canvas in Safari?
Is it simply that SVGImageElement
is not supported, but a regular Image
is, and you can simply set the src
on an image to an svg
, and then it works fine?
If that is indeed the case, then does it really matter that SVGImageElement
is not supported in Safari? You can still draw SVGs onto the canvas regardless by just using a regular Image and setting the src to be an svg asset file?
Do I have that right?
Solution
That’s a bug, you should report it to webkit’s bug-tracker.
Though you can workaround it by first drawing the image on a second canvas just to rasterize that svg image and use that canvas as source for the shadowing:
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var image = new Image();
image.src = 'https://storage.googleapis.com/card-conjurer/img/manaSymbols/0.svg';
image.onload = function() {
const off = canvas.cloneNode();
off.getContext('2d').drawImage(image, 10, 10, 100, 100);
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowColor = 'red';
context.drawImage(off, 0, 0);
}
<canvas id='canvas'></canvas>
In order to use a single canvas, we need to use an offset trick, but it’s not always easy to do since it requires knowing clearly the position of our drawing:
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var image = new Image();
image.src = 'https://storage.googleapis.com/card-conjurer/img/manaSymbols/0.svg';
image.onload = function() {
// first pass without shadow
context.drawImage(image, 10, 10, 100, 100);
// set shadow offsets to the position in page of bottom-right corner
context.shadowOffsetX = 10 + 110;
context.shadowOffsetY = 10 + 110;
context.shadowColor = 'red';
// draw behind
context.globalCompositeOperation = "destination-over";
// draw with inverse offset, so that the image is not visible
// but the shadow is in-screen
context.drawImage(canvas, -110, -110);
}
<canvas id='canvas'></canvas>
This Question was asked in StackOverflow by ImKyle4815 and Answered by Kaiido It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.