本文适合适合对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, 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>>

如何解决

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

  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, 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、前端可视化方面有深入研究。对程序员思维能力训练和培训、程序员职业规划有浓厚兴趣。

ITman彪叔公众号

FireFox下Canvas使用图像合成绘制SVG的Bug相关推荐

  1. [Web Chart系列之一(续)]Web端图形绘制SVG,VML, HTML5 Canvas 简单实例

    前言 本篇是继 [Web Chart系列之一]Web端图形绘制SVG,VML, HTML5 Canvas 技术比较 的补充和实例说明各种技术的使用方式. VML 的用法和实例 引入命名空间之后,就可以 ...

  2. [Web Chart系列之一]Web端图形绘制SVG,VML, HTML5 Canvas 技术比较

    先介绍一下矢量图的概念: 矢量图使用直线和曲线来描述图形,这些图形的元素是一些点.线.矩形.多边形.圆和弧线等等,它们都是通过数学公式计算获得的.例如一幅花的矢量图形实际上是由线段形成外框轮廓,由外框 ...

  3. canvas 元素绑定事件_绘制SVG内容到Canvas的HTML5应用

    SVG与Canvas是HTML5上绘制图形应用的两种完全不同模式的技术,两种绘制图形方式各有优缺点,但两者并非水火不容,尤其是SVG内容可直接绘制在Canvas上的功能,使得两者可以完美的融合在一起, ...

  4. html5 svg组态图,绘制SVG内容到Canvas的HTML5应用

    SVG与Canvas是HTML5上绘制图形应用的两种完全不同模式的技术,两种绘制图形方式各有优缺点,但两者并非水火不容,尤其是SVG内容可直接绘制在Canvas上的功能,使得两者可以完美的融合在一起, ...

  5. HTML5 Canvas、内联 SVG、Canvas vs. SVG

    canvas 元素用于在网页上绘制图形. 什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canv ...

  6. firefox html5 canvas,html5 Canvas

    什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canvas 拥有多种绘制路径.矩形.圆形.字符以 ...

  7. html5拓扑图图入门,如何使用HTML5 Canvas动态的绘制拓扑图

    如何使用HTML5 Canvas动态的绘制拓扑图 使用HTML5 Canvas动态的绘制拓扑图: HTML5中引入新的元素canvas,其drawImage 方法允许在 canvas 中插入其他图像( ...

  8. canvas 圆角矩形填充_View绘制系列(9)Canvas八卦图绘制

    Canvas八卦图绘制 前面我们已经学习了Path.quadTo(float x1, float y1, float x2, float y2)及Path.cubicTo(float x1, floa ...

  9. Canvas学习:绘制箭头

    原文出处:https://www.w3cplus.com/canvas/drawing-arrow.html (本文对错误做了纠正,博主有一系列实用Canvas教程) 在这篇文章中主要来聊在Canva ...

最新文章

  1. Yii框架控制台报错: The id configuration for the Application is required
  2. 《几何与代数导引》例2.6
  3. 马拦过河卒(NOIP2002)
  4. 全球及中国6氯5氨基邻甲酚行业深度调研与运营潜力分析报告2022版
  5. Android 5.x Theme 与 ToolBar 实战
  6. python如果选择不在列表里_Python-list.remove(x)x不在列表中
  7. 深度学习笔记(38) 非极大值抑制
  8. 用以太坊区块链保证Asp.Net Core的API安全(上)
  9. JSpider(3):JSpider的结构
  10. 主席树 POJ2104
  11. python read_csv dtype_Pandas read_csv low_memory和dtype选项
  12. 成功软文营销经典案例-案例分享
  13. Matlab实现熵权法并计算权重和综合评分——附增完整代码和测试用例
  14. VB获取一个文件夹中指定的文件或文件夹名称到列表
  15. MATLAB实现Enigma 密码机
  16. PHP给PDF文件加水印(mpdf插件)
  17. 软考中级 真题 2015年上半年 信息系统管理工程师 应用技术
  18. C++弹幕游戏自制分享
  19. 笔记本高分屏字体模糊_高分屏字体模糊win10怎么办_Win10系统高分屏字体模糊解决方法...
  20. 0672-5.16.1-CDSW中Run Experiments异常分析

热门文章

  1. Hihocoder 顺子
  2. 2021-2027全球与中国MPO连接器市场现状及未来发展趋势
  3. 设置和取消Excel限制保护的两种方法
  4. 用SQL语句修改表结构和添加约束
  5. 无人机——开源飞控简介
  6. 第3.8节 Python百分号占位符的字符串格式化方法
  7. 信息安全实验六:RSA数字签名算法 2019.06.01
  8. 【题解】纪中篮球联赛
  9. UE4 统计数据命令描述
  10. Android中的自定义View(一)