我正在创建html5绘画应用程序,我目前正致力于混合图层。我想知道哪种方法是最好的(最快和gimp / photoshop)在这样的程序中构建。我的图层(画布)堆叠在一起。
我正在使用第二种方法,但我不确定它是最好的(特别是对于更多层)。我想知道你知道任何其他方法,也许你会建议什么是更好的实现混合操作,使其像Gimp / Adobe Photoshop一样工作
答案 0 :(得分:0)
我实现这一点的方法是拥有多个画布,每个画布都存储着自己的混合模式。但它只是虚拟画布(不适合用户使用)。然后每秒33次计时器(由RequestAnimationFrame制作)抓住所有这些画布,展平它们并将其绘制到视口。对于每个图层,我在视口画布上执行混合模式更改。它工作得很完美,因为drawImage(...)是在GPU上计算的,而且速度非常快。
我认为代码很容易理解并适用于自己的解决方案:
Process(lm: dl.LayerManager) {
var canvasViewPort = lm.GetWorkspaceViewPort();
var virtualLayers = lm.GetAllNonTemporary();
canvasViewPort.Save();
canvasViewPort.Clear();
canvasViewPort.SetBlendMode(virtualLayers[0].GetBlendMode());
canvasViewPort.ApplyBlendMode();
canvasViewPort.DrawImage(virtualLayers[0], 0, 0, canvasViewPort.Width(), canvasViewPort.Height(), 0, 0, canvasViewPort.Width(), canvasViewPort.Height());
for (var i = 1; i < virtualLayers.length; ++i) {
var layer = virtualLayers[i];
var shift = other.GetShift();
canvasViewPort.SetBlendMode(virtualLayers[i].GetBlendMode());
canvasViewPort.ApplyBlendMode();
canvasViewPort.DrawImage(layer, 0, 0, layer.Width(), layer.Height(), shift.x, shift.y, layer.Width(), layer.Height());
}
canvasViewPort.Restore();
}
不要害怕这段代码。它保持底层画布,纯CanvasRenderingContext2D。
我将执行此类优化:在任何虚拟画布上发生更改之前,我不会重绘canvasViewPort。
我将执行下一个优化:获取所选图层,在当前图层之前和之后全部缓存。
所以它看起来像:
CurrentLayer:3(可能受某些工具影响)
[1]:L1
[2]:L2
[3]:L3
[4]:L4
[5]:L5
[6]:L6
使用适当的混合模式[1,2]到tmp1和[4,5,6]到tmp2绘制临时。 当第三层发生变化时,我只需重新绘制tmp1 + [3] + tmp2。 所以它只是2次迭代。超快。