绘制重叠的半透明线条,没有可见的重叠

时间:2011-12-07 09:18:54

标签: html5 canvas vector-graphics

我正在使用HTML5画布开发一个画家程序。我创建了一个绘图工具,用户拖动并移动鼠标。

我在mousemove事件中有一个听众,它会画出短线:

Painter.mainCanvas.beginPath();
Painter.mainCanvas.moveTo(Painter.lastX, Painter.lastY);
Painter.lastX = e.offsetX;
Painter.lastY = e.offsetY;
Painter.mainCanvas.lineTo(Painter.lastX, Painter.lastY);
Painter.mainCanvas.stroke();

一切正常,直到我将全局Alpha设置为< 1.使用此方法绘制时,结束点也是起点。所以点画了两次。而且因为我们有透明的颜色,所以点现在有不同的颜色与其他点在一起。

我尝试了另一种方法,当mousemoves触发时,它只会在mouseup触发时使用lineTo()stroke()

这解决了双重绘图问题,但也引入了一个新问题:当用户打算两次绘制相同的点时,即没有鼠标的交叉线时,点将不会被绘制两次。因为lineTo()函数不会在没有笔划的情况下绘制两次点。

1 个答案:

答案 0 :(得分:20)

(重述您的问题)您最初的问题是,通过为每个细分受众群调用beginPath()stroke(),您有许多重叠的半透明路径。您的新“问题”是,通过将所有lineTo()命令创建为同一路径的一部分,然后在结尾处调用stroke() 一次任何自相交路径用户不会显示可见的重叠。

以下示例显示了制作

之间的区别
  • 单条路径中的许多半透明线条和一次(左上角)相对于
  • 许多不同路径中的半透明线条和每个(右下角)

http://jsfiddle.net/jhyG5/2/

A semi-transparent set of crossing lines (all the same opacity) in the upper left and a set of crossing lines with increasing opacity where they cross in the bottom right.

我会说你当前的解决方案(单一路径)是正确的方法,即使单个自交路径不会在不透明度上加倍。这是您在绘制半透明路径时在Adobe Photoshop和Illustrator中看到的内容:使用鼠标向下绘制的所有绘图都是相同的单个非重叠透明对象的一部分。只有当用户释放并重新按下鼠标按钮时,才会累积更多透明度:

  • 两个不透明度为50%的Photoshop画笔描边:
    Photoshop Overlapping Style

  • 两个不透明度为50%的Illustrator路径: Illustrator Overlapping Strokes

特别注意自相交行程和路径在交叉过程中不会显示不透明度的两倍,但是单独的新路径会显示。

我建议您坚持使用当前的解决方案,因为这就是这些传统的,经过深思熟虑的应用程序的行为方式。我之所以这么说,是因为你希望你的软件包能够模仿用户的期望,而且因为如果这些软件包像这样做的话,可能有一个很好的理由:你原来遇到的确切问题! :)