详解FireFox下Canvas使用图像合成绘制SVG的Bug
全部的工作城市有一个因由。 最近产物上必要做一个这样的成果:给一些图形举办染色处理赏罚。想想这还不是随手拈来的工作,早就研究过图形染色的技能。于是我把之前写好的两种算法发给了小搭档,让他参照实现,第一种算法是哄骗像素、第二种行使了图像合成:globalCompositeOperation。 全部的工作都也许会有不测,写措施更是云云了。 没多久,小搭档说,第二种算法在firefox下不起浸染。 试探缘故起因 传闻有bug,心中一惊。我测试过了的,FireFox下面也测试过的。于是我打开火狐赏识器,启动示例,发明是好的,没有题目。 可是小搭档集成到产物中就有题目。 不同在哪儿呢? 通过一路排查,最终发明我的示例代码和产物中代码的一个区别是:示例代码用的是png图片,而产物顶用的是svg图片。 莫非是svg图片的题目,拿一个svg图片放到示例代码中,公然差池。结论已经明明: FireFox赏识器下,用Canvas下绘制绘制SVG图的时辰,globalCompositeOperation的配置将不见效。 下面是一段用于测试的代码,ctx.globalCompositeOperation = 'destination-out' 暗示用源图像的外形去挖空方针图像。 在其他赏识器中,以下代码中是见效的,又挖空的结果。可是在 在FireFox 下不见效: <html> <head> <script> function init() { var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = new Image(); img.onload = function () { ctx.drawImage(img, 0, 0, img.width * 2, img.height * 2); ctx.globalCompositeOperation = 'destination-out'; } img.src = 'diffuse.png'; var svg = new Image; svg.src = "./d.svg"; function drawPoint(pointX, pointY) { ctx.drawImage(svg, pointX - svg.width / 4, pointY - svg.height / 4, svg.width / 2, svg.height / 2); } canvas.addEventListener('click', function (e) { drawPoint(e.clientX, e.clientY); }, false); } </script> </head> <body onload="init();" style="background: red"> <div> <canvas id="c" width="1000" height="1000"></canvas> </div> </body> </html> 怎样办理 找到题目的缘故起因了,办理要领着实简朴。 工作每每就是这样,许多时辰,找到题目地址每每比办理题目要难。 办理方案着实很简朴 代码中插手判定,判定浏赏识器是否是FireFox。 假如是,则先把svg图片绘制到姑且的canvas上面。 后续绘制用姑且的canvas更换svg图片。 好比上面代码可以改造如下: function init() { var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = new Image(); img.onload = function () { ctx.drawImage(img, 0, 0, img.width * 2, img.height * 2); ctx.globalCompositeOperation = 'destination-out'; } img.src = 'diffuse.png'; var svg = new Image; svg.src = "./d.svg"; var tempCanvas = svg; if(isFirefox){ svg.onload = function(){ tempCanvas = document.createElement('canvas'); tempCanvas.width = svg.width; tempCanvas.height = svg.height; var tempCtx = tempCanvas.getContext('2d'); tempCtx.drawImage(svg,0,0,svg.width,svg.height); } } function drawPoint(pointX, pointY) { ctx.drawImage(tempCanvas, pointX - svg.width / 4, pointY - svg.height / 4, svg.width / 2, svg.height / 2); } canvas.addEventListener('click', function (e) { drawPoint(e.clientX, e.clientY); }, false); } (编辑:河北网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |