jjzjj

javascript - 用于叠加渐变的 HTML5 Canvas globalCompositeOperation 不会增加更高的强度?

coder 2024-05-09 原文

我目前正在研究 heatmap.js修复,我想知道是否有人知道是否可以使用 <canvas> 实现以下效果的 2d 渲染上下文。

  • 我有一个从黑色(alpha 0.5)到透明 40 像素半径的径向渐变。径向梯度的中心在 x=50, y=50
  • 我有另一个从黑色(alpha 0.5)到透明的径向渐变,半径为 40 像素。径向梯度的中心在 x=80, y=50

两个渐变是重叠的。我现在的问题是:重叠区域被加在一起导致比径向梯度中心更高的 alpha 值,从而显示错误的数据(例如,由于梯度之间的这些添加,热图中更热的区域)

看看下面的gist ,通过在您的控制台中执行它,您可以看到问题所在。

预期的行为是: 最暗的区域是渐变中心,两个渐变的重叠区域合并但不相加。

在看到所有 globalCompositeOperations 都没有产生预期的行为后,我尝试了这些操作的组合。 我认为可能的一种方式如下:

  • 绘制第一个渐变
  • 使用 compositeOperation 'destination-out'
  • 绘制第二个渐变 -> 从第一个渐变中减去重叠区域
  • 使用 compositeOperation 'source-over'
  • 再次绘制第二个渐变

但不幸的是,我没有找到有效的组合。我很想听听您的反馈,在此先感谢您!

PS:我知道这可以通过手动操作像素来完成,但我想知道是否有更简单、更优雅、更快速的解决方案。

最佳答案

这确实很古怪,但它可以在不涉及 imageData 的情况下完成您想要的操作。

我想到的是,当您抚摸它们时,您想要路径本身在 Canvas 上具有的确切功能。引用规范:

As a result of how the algorithm to trace a path is defined, overlapping parts of the paths in one stroke operation are treated as if their union was what was painted.

您可以阅读更多相关信息 here.

无论如何,从本质上讲,您想要的是一条模糊的路径,只有弧线,您可以划一次,就可以完美地获得您想要的效果。

唯一的问题是无法在 Canvas 中制作模糊路径。或者几乎没有办法。

除了使用路径本身,我们还可以使用路径的阴影来模拟遵循与路径相同规则的模糊圆圈。

唯一的问题是,您不想看到实际路径,只想看到它的影子。使笔划透明是行不通的:阴影只会绘制,不会以比其阴影对象更高的不透明度进行绘制。

但是阴影确实具有属性 shadowOffsetXshadowOffsetY,它们通常用于将阴影移动一两个像素以产生光源的错觉。

但是,如果我们将阴影画得很远以至于你看不到它们呢?或者更确切地说,如果我们将路径画得离您太远以至于您看不到它们,您只能看到阴影会怎么样?

好吧,这恰好可以解决问题。这是一个快速结果,您的原始代码在顶部,阴影是第二个 Canvas :

在渐变和大小方面,这与您之前所拥有的并不完全相同,但它非常接近,我相信通过调整这些值,您可以使它更接近。几个 console.log 确认我们想要的东西,一个不超过 124(超过 255)的 alpha 正确地出现在它曾经是 143 和 134 的地方,以旧的方式进行。

查看实际代码的 fiddle :http://jsfiddle.net/g54Mz/

就是这样。如果您使用阴影并将实际路径偏移到屏幕之外,则无需 imageData 即可获得两个径向渐变的联合效果。

关于javascript - 用于叠加渐变的 HTML5 Canvas globalCompositeOperation 不会增加更高的强度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10060242/

有关javascript - 用于叠加渐变的 HTML5 Canvas globalCompositeOperation 不会增加更高的强度?的更多相关文章

随机推荐