`
flyfox1982
  • 浏览: 81067 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

阅读更多

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

楔子

所有的事情都会有一个起因。
最近产品上需要做一个这样的功能:给一些图形进行染色处理。想想这还不是顺手拈来的事情,早就研究过图形染色的技术。于是我把之前写好的两种算法发给了小伙伴,让他参照实现,第一种算法是操纵像素、第二种使用了图像合成: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, 00, 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>>

如何解决

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

  1. 代码中加入判断,判断浏浏览器是否是FireFox。
  2. 如果是,则先把svg图片绘制到临时的canvas上面。
  3. 后续绘制用临时的canvas替代svg图片。
    比如上面代码可以改进如下:
function init() {
            var canvas = document.getElementById('c');
            var ctx = canvas.getContext('2d');
            var img = new Image();
            img.onload = function () {
                ctx.drawImage(img, 00, 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、前端可视化方面有深入研究。对程序员思维能力训练和培训、程序员职业规划有浓厚兴趣。

ITman彪叔公众号ITman彪叔公众号

0
0
分享到:
评论

相关推荐

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

    于是我把之前写好的两种算法发给了小伙伴,让他参照实现,第一种算法是操纵像素、第二种使用了图像合成:globalCompositeOperation。 所有的事情都可能会有意外,写程序更是如此了。 没多久,小伙伴说,第二种算法在...

    html2canvas(兼容截图svg元素)

    `canvg`是一个专门用来在Canvas上渲染SVG的库,它能够解析SVG文档并将其绘制到Canvas元素上。当`html2canvas`遇到SVG元素时,通过先用`canvg`将SVG渲染到Canvas,然后再让`html2canvas`处理,可以有效地解决SVG截图...

    canvas+svg实现标尺网格效果

    使用js+canvas绘图,结合svg图形,实现标尺栏和网格效果。

    svg转img所需 html2canvas方法,svg转canvas所需canvg方法

    // 使用canvg将SVG绘制到Canvas canvg(canvas, svgData); ``` 以上就是使用`html2canvas`和`canvg`库进行SVG到IMG以及SVG到CANVAS转换的方法。在实际应用中,根据项目需求,可能还需要处理SVG的样式、透明度、...

    canvas2svg:将HTML5 Canvas绘制命令转换为SVG

    该库使用JavaScript将Canvas转换为SVG。 换句话说,该库使您可以使用canvas api构建SVG文档。 为什么要使用它? 您有一个要作为SVG文件保留的画布图形。 您喜欢导出内容。 因为您不想将自定义文件格式转换为SVG...

    使用Canvas类绘制android机器人

    在Android开发中,Canvas是图形绘制的核心类,它允许开发者在Bitmap或者其他可绘图对象上进行画图操作。本文将深入探讨如何利用Canvas类来绘制一个Android机器人,从而理解其基本概念、方法以及如何实现复杂的图形...

    将svg画布内容转成canvas,转换成png图片下载

    以上就是在IE环境下将SVG内容转换为Canvas并导出为PNG图片的基本步骤。在实际应用中,你可能还需要处理SVG的样式、透明度、以及错误处理等问题。`svg_canvas_png`压缩包文件可能包含了示例代码或进一步的辅助工具,...

    canvas 合成 文字 图片

    在前端开发中,Canvas是HTML5提供的一种强大的图形绘制API,可以用来动态生成图像、进行图像处理和合成。本文将详细介绍如何使用Canvas进行文字与图片的合成,通过一个简单的入门Demo来展示具体实现过程。 首先,...

    酷炫的svg与canvas结合动画.zip

    - 通过将SVG作为Canvas的图像源,可以在Canvas上绘制SVG图形,同时享受Canvas的动画性能。 - 也可以在SVG中嵌入Canvas,为特定区域提供更灵活的动态渲染。 5. **JavaScript在其中的角色**: - JavaScript是连接...

    WPF 使用 Skia 解析绘制 SVG 图片.rar

    **WPF 使用 Skia 解析绘制 SVG 图片** 在Windows Presentation Foundation (WPF) 中,SVG(Scalable Vector Graphics)图像是一种常见的图形格式,它提供了高质量、可缩放的矢量图形。SVG图像通常用于网页设计、...

    Canvas渲染引擎,支持SVG,兼容了小程序、小游戏和Web.zip

    SVG(Scalable Vector Graphics)则是一种基于XML的矢量图像格式,可以在任何分辨率下保持清晰,非常适合用于创建复杂的图形和图表。在这个压缩包"Canvas渲染引擎,支持SVG,兼容了小程序、小游戏和Web.zip"中,包含...

    SVG和Canvas绘图:使用Canvas绘制基本图形.docx

    SVG和Canvas绘图:使用Canvas绘制基本图形.docx

    wxml2canvas微信根据wxml绘制海报

    ##根据wx.createSelectorQuery()获取wxml的'color','font-size','font-weight','font-family','backgroundColor','border','border-...##wx.createCanvasContext绘制海报,而不是canvas2d绘制海报,海报高度没限制

    基于canvas的流程图绘制程序

    1. **canvas API的使用**:在canvas上绘制流程图,首先要获取canvas元素,然后通过`getContext('2d')`方法获取2D渲染上下文。所有的绘图操作,如画线、填充形状、设置线条样式等,都是通过对这个2D渲染上下文进行...

    Canvas画布图片文字拼接合成,生成图片

    downloadLink.download = '合成图片.png'; downloadLink.click(); ``` 6. **邀请函示例应用** 在`invitation`这个场景中,用户可以输入自定义的邀请内容,程序动态生成带有这些文字的邀请函图片。可能包括预设...

    HTML5 Canvas+SVG实现的彩色水泡分裂动画特效源码.zip

    SVG(Scalable Vector Graphics)则是另一种图形表示方式,它使用矢量图形来描绘图像,这意味着无论放大多少倍,图像都不会失真。SVG特别适合于创建复杂的图形和图标,尤其适用于需要动态交互和响应式设计的场景。在...

    Canvas详解及代码绘制安卓机器人

    Canvas是Android系统中用于2D图形绘制的核心组件,它提供了丰富的功能来在屏幕上画出各种形状、图像和文字。在Android应用开发中,Canvas经常被用来实现自定义视图、动画效果以及游戏画面等。本篇文章将深入解析...

    SVG、CANVAS、VML比较

    SVG(Scalable Vector Graphics)是一种基于XML的开放标准,被广泛支持,尤其在现代浏览器中,如Firefox和Opera。在Internet Explorer中,虽然早期版本需要Adobe SVG Viewer插件,但后来的版本开始内建对SVG的支持。...

    Canvas饼状图、绘制文字、绘制图像.zip

    这个压缩包文件"Canvas饼状图、绘制文字、绘制图像.zip"显然包含了关于如何使用Canvas进行特定图形绘制的教程或示例,特别是饼状图、文字和图像的绘制方法。 首先,让我们详细了解一下饼状图的绘制。饼状图是一种...

    canvas鼠标绘制多边形

    使用canvas 鼠标事件绘制多边形,鼠标按下事件,移动事件绘制,双击事件结束绘制。原生js,使用添加事件监听,移除事件监听方法来进行绘制开始和结束。简单小demo

Global site tag (gtag.js) - Google Analytics