I'm using HTML5 canvas in a project and occasionally need to draw drop shadows on SVGs within a canvas. I've noticed that, compared to Chrome, Safari does two things incorrectly when doing this:
These issues can be illustrated by the following code:
var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); context.shadowOffsetX = 10; context.shadowOffsetY = 10; context.shadowColor = 'red' var image = new Image(); image.src = 'https://storage.googleapis.com/card-conjurer/img/manaSymbols/0.svg'; image.onload = function() { context.drawImage(image, 10, 10, 100, 100); }
<canvas id='canvas'></canvas>
I can't embed images yet, but here are some links to images that illustrate the problem:
(they are screenshots of the code above)
The results from Safari are... quite ugly, as you can see. Is there a way make Safari to render SVGs with shadows on HTML5 canvas like Chrome does?
Any help would be greatly appreciated. Thanks so much for your time!
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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.