资讯专栏INFORMATION COLUMN

FireFox下Canvas使用图像合成绘制SVG的Bug

mudiyouyou / 2150人阅读

摘要:本文适合适合对绘制图形学前端可视化感兴趣的读者阅读。结论已经明显浏览器下,用下绘制绘制图的时候,的设置将不生效。下面是一段用于测试的代码,表示用源图像的形状去挖空目标图像。后续绘制用临时的替代图片。

本文适合适合对canvas绘制、图形学、前端可视化感兴趣的读者阅读。
楔子

所有的事情都会有一个起因。
最近产品上需要做一个这样的功能:给一些图形进行染色处理。想想这还不是顺手拈来的事情,早就研究过图形染色的技术。于是我把之前写好的两种算法发给了小伙伴,让他参照实现,第一种算法是操纵像素、第二种使用了图像合成:globalCompositeOperation。
所有的事情都可能会有意外,写程序更是如此了。
没多久,小伙伴说,第二种算法在firefox下不起作用。

探索原因

听说有bug,心中一惊。我测试过了的,FireFox下面也测试过的。于是我打开火狐浏览器,启动示例,发现是好的,没有问题。
但是小伙伴集成到产品中就有问题。 差别在哪儿呢? 通过一起排查,最终发现我的示例代码和产品中代码的一个区别是:示例代码用的是png图片,而产品中用的是svg图片。
难道是svg图片的问题,拿一个svg图片放到示例代码中,果然不对。结论已经明显:
FireFox浏览器下,用Canvas下绘制绘制SVG图的时候,globalCompositeOperation的设置将不生效。
下面是一段用于测试的代码,ctx.globalCompositeOperation = "destination-out" 表示用源图像的形状去挖空目标图像。
在其他浏览器中,以下代码中是生效的,又挖空的效果。但是在
在FireFox 下不生效:



    


    
>
如何解决

找到问题的原因了,解决方法其实简单。
事情往往就是这样,很多时候,找到问题所在往往比解决问题要难。
解决方案其实很简单

代码中加入判断,判断浏浏览器是否是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);
        }

欢迎关注公众号“ITman彪叔”。彪叔,拥有10多年开发经验,现任公司系统架构师、技术总监、技术培训师、职业规划师。熟悉Java、JavaScript、Python语言,熟悉数据库。熟悉java、nodejs应用系统架构,大数据高并发、高可用、分布式架构。在计算机图形学、WebGL、前端可视化方面有深入研究。对程序员思维能力训练和培训、程序员职业规划有浓厚兴趣。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105500.html

相关文章

  • SVG粗谈

    摘要:和确定的版本指定的宽高指定命名空间。的曲线就是使用画的。等等元素元素是用来组合对象的容器。添加到元素的属性会被其所有的子元素继承。是基于矢量的,可以很好的处理图像大小变化。而是基于位图的,无法进行大小变化。 背景 最近一直在做报表之类的需求,用highcharts比较多。highcharts使用svg进行绘图,所以学习了一下svg,稍微记录一下。 概况 svg是XML语言的一种形式。S...

    el09xccxy 评论0 收藏0
  • 数据可视化实践

    摘要:但如果数据可视化做的较弱,反而会带来负面效果错误的表达往往会损害数据的传播,完全曲解和误导用户,所以更需要我们多维的展现数据,就不仅仅是单一层面,目前有多种第三方库来实现数据的可视化等。数据可视化的具体实现这里基于两种实现方式,一种一种。 数据可视化的目的其实就是直观地展现数据,例如让花费数小时甚至更久才能归纳的数据量,转化成一眼就能读懂的指标;通过加减乘除、各类公式权衡计算得到的两组...

    PrototypeZ 评论0 收藏0

发表评论

0条评论

mudiyouyou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<