简体   繁体   English

Safari 通过 HTML5 在 SVG 上错误地绘制阴影 Canvas

[英]Safari incorrectly drawing shadows on SVGs via HTML5 Canvas

I'm using HTML5 canvas in a project and occasionally need to draw drop shadows on SVGs within a canvas.我在项目中使用 HTML5 canvas,偶尔需要在 canvas 内的 SVG 上绘制阴影。 I've noticed that, compared to Chrome, Safari does two things incorrectly when doing this:我注意到,与 Chrome 相比,Safari 在执行此操作时会错误地做两件事:

  1. Safari draws a shadow on each individual shape within an SVG Safari 在 SVG 内的每个单独形状上绘制阴影
  2. Safari crops off parts of the shadow that go beyond the SVG's bounds Safari 裁剪掉 go 超出 SVG 范围的部分阴影

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. Safari 的结果...非常难看,如您所见。 Is there a way make Safari to render SVGs with shadows on HTML5 canvas like Chrome does?有没有办法让 Safari 像 Chrome 一样在 HTML5 canvas 上渲染带有阴影的 SVG?

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 .这是一个错误,你应该将它报告给webkit 的 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:尽管您可以通过首先在第二个 canvas 上绘制图像来解决此问题,以光栅化 svg 图像并使用该 canvas 作为阴影源:

 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:为了使用单个 canvas,我们需要使用偏移技巧,但这并不总是容易做到,因为它需要清楚地知道我们绘图的 position:

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM