【问题标题】:Custom globalCompositeOperation in html5 Canvashtml5 Canvas 中的自定义 globalCompositeOperation
【发布时间】:2016-04-06 08:43:14
【问题描述】:

我在这里查看所有不同类型的全局复合操作:

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation

他们都没有做我想做的事。有没有办法定义自定义 globalCompositeOperation?如果我可以创建一个着色器,然后在每次使用 CanvasRenderingContext2D.draw 方法绘制某些东西时使用它,那将是完美的。

具体来说,在每个像素的基础上,我希望 CanvasRenderingContext2D.draw 方法使用以下(伪代码)操作:

if the existing canvas color alpha is 0.0, 
    then draw the new shape's color and set alpha to 0.1
if the existing canvas color is the same as the new shape's color
    then increase the alpha, by 0.1
if the existing canvas color is different from the the new shape's color
    then decrease the alpha by 0.1

我是否正确地考虑了这一点?我感觉我应该以某种方式使用 WebGLRenderingContext,但我对它们如何组合在一起有点犹豫。

【问题讨论】:

  • 简短回答:不,你不能(或没有太多工作)。你应该在网上搜索,有各种各样的项目使用 webgl 进行图像处理,你可以轻松修改以适应你的需要。不要忘记 FF 和 Chrome 现在都提供了很棒的 webgl 调试工具。
  • 您可以为 webGL 重构您的代码并获得着色器的好处。但是不要尝试扩展 CanvasRenderingContext2D —— 不需要。但是您可以使用现有画布和另一个内存画布轻松创建自己的自定义图像过滤器功能。内存中的画布将保存新图纸。然后在两个画布上 getImageData 并根据您的自定义混合操作比较 + 操作 + 替换现有画布上的每个像素。注意:这是相当资源和 cpu 密集型的,因为使用 getImageData 进行合成无法卸载到 gpu。

标签: html5-canvas webgl globalcompositeoperation


【解决方案1】:

答案大部分是否定的。

无法使用 Canvas2D 定义您自己的globalCompositeOperation

2 个解决方案让我头疼

  1. 使用 2 个画布,一个 2d 和一个 WebGL

    for each shape
       clear the 2d canvas
       draw the shape into the 2d canvas
       upload the canvas to a webgl texture
       composite that texture with the previous results using a custom shader.
    

    这个解决方案的问题是它会很慢,因为将画布上传到纹理是一个相对较慢的操作。但是,这意味着您可以使用所有的画布函数,如 strokearc 以及渐变等来构建它的形状。

  2. 完全切换到 WebGL

    这里的问题是您无法访问 2D API 的所有功能,并且复制所有这些功能需要大量工作。

    另一方面,如果您只使用有限的一组,那么工作量可能不会太大。例如,如果您只使用drawImagefillRectclear,可能还有moveTolineTofillstroke,那么在WebGL 中重现相对容易。如果您使用了许多功能,例如遮罩、贝塞尔曲线、渐变或图案,它开始变得更加工作。

作为初学者here's a tutorial that presents a certain kind of compositing or image processing,这是WebGL 中globalCompositeOperation 的基本技术。上述两种解决方案都需要这种基本类型的解决方案来组合每个shape 之后的结果。

【讨论】:

  • “复制 [所有 context2D] 功能需要大量工作”:是的,但使用执行此操作的 API(或为 O.P. 提供足够的功能)仍然是可能的。我知道 pixi.js,也许其他一些人也这样做。
  • Pixi 不会重现画布 API。它基本上提供了 1 个且仅 1 个函数,drawImage 在其之上创建了一个场景图。这就是我上面的观点,如果您只使用 canvas 2d api 的一些基本功能,那么回购并不难。我不知道任何接近在 WebGL 中重现 canvas 2d api 的 JS 库。如果您知道一些,请在下面发布。我知道的唯一一个是 this one,它已被废弃 5 年,并且缺少大量功能。
  • 也许您说的是 Pixi 的第一个版本。现在它有线条、贝塞尔曲线、多边形......也许不是你想要的,但仍然比 drawImage 多得多。 (goodboydigital.com/pixijs/docs/classes/Graphics.html)。抱歉,我不知道还有什么其他选择。
  • 哦,太好了!我没注意。
  • 感谢@gman 的精彩回答。我只是将此标记为答案。您对这两个选项的解释非常有帮助。事实上,我使用了相当多的绘图 api,包括贝塞尔曲线,所以我实际上一直在使用你建议的双画布方法作为第一个解决方案(成功有限,因为我对 webgl 非常陌生并且没有' t 解决了所有的错误)。
猜你喜欢
  • 2011-02-20
  • 1970-01-01
  • 2012-04-21
  • 2011-09-14
  • 2011-10-27
  • 1970-01-01
  • 2018-12-29
  • 2022-01-03
  • 2015-05-28
相关资源
最近更新 更多