在 HTML5 Canvas 中实现图层
我即将在 HTML5 Canvas 中实现类似 Photoshop 的图层。目前我有两个想法。第一个也许更简单的想法是为每个图层设置一个 Canvas 元素,如下所示:
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
这样,当您绘制到图层时 - 它实际上会到达该“图层”。具有透明位置的图层可以看到下面的图层(画布)。层堆叠由 z-index
属性控制。
第二个想法是使用单个 Canvas 元素并实现一些逻辑来处理层,如本例所示:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script>
window.addEventListener('load', function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var order = 0;
function drawLayer1() {
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
}
function drawLayer2() {
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
function draw() {
ctx.clearRect(0, 0, 256, 256);
if (order === 0) {
drawLayer1();
drawLayer2();
}
else {
drawLayer2();
drawLayer1();
}
}
setInterval(draw, 250);
setInterval(function() {
order = 1 - order;
}, 200);
}, false);
</script>
</head>
<body>
<canvas id="canvas" width="256px" height="256px"></canvas>
</body>
</html>
在上面的代码中,两个层将每 200 毫秒更改一次堆叠顺序。
那么,问题是哪种方式是最好的方式?两种方法的优缺点是什么?
I am about to implement Photoshop-like Layers in HTML5 Canvas. Currently I have two ideas. The first and maybe the simpler idea is to have a Canvas element for each layer like:
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
This way when you draw to a layer -- it actually goes to that "layer". Layers with transparent positions can be seen through to below layers (Canvases). Layer stacking is controlled with z-index
property.
The second idea is to use a single Canvas element and implement some logic to handle layers like in this case:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script>
window.addEventListener('load', function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var order = 0;
function drawLayer1() {
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
}
function drawLayer2() {
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
function draw() {
ctx.clearRect(0, 0, 256, 256);
if (order === 0) {
drawLayer1();
drawLayer2();
}
else {
drawLayer2();
drawLayer1();
}
}
setInterval(draw, 250);
setInterval(function() {
order = 1 - order;
}, 200);
}, false);
</script>
</head>
<body>
<canvas id="canvas" width="256px" height="256px"></canvas>
</body>
</html>
In the above code the two layers will change stacking order every 200msec.
So, the question is that which way would be the best way? What are the pros and cons of both approaches?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您想使用单个画布元素并在其中包含多个层,您可能需要查看我的库:
它使用损坏的矩形系统来减少每次画布更改时重新绘制的数量,因此您不仅可以获得图层(可以嵌套),还可以获得优化的重绘。
If you want to use a single canvas element and have multiple layers inside it, you might want to look at my library:
It uses a damaged rect system to reduce the amount of repainting done every time the canvas changes, so not only do you get layers (which can be nested), but you also get optimised redraws.
使用多个画布应该会更快,因为画布会在屏幕外绘制,然后由浏览器传输到屏幕。您将切换图层的负担放在浏览器上,浏览器只需移动一些图形数据的矩形即可。
如果你自己分层,你就有更多的控制权,但所有工作的负担都落在了 JS 和 JS 引擎身上。如果我有选择,我会避免这种情况,但如果您想要在底层上工作的图层效果,这可能是您唯一的选择。
Using multiple canvases should be faster, because the canvas gets drawn off-screen and then just blitted to the screen by the browser. You put the burden of switching layers on the browser, which just has to move some rectangles of graphics data around.
If you do the layering yourself, you have more control, but the burden is on the JS and the JS engine to do all the work. I would avoid this if I had a choice, but if you're going for layer effects that work on the underlying layers, this might be your only choice.
设置容器 div 相对值应该可以防止图层覆盖问题。尝试设置“遮挡文本”上的位置 - 例如,如果它当前是绝对的,那么它显然会位于与相关内容的左上角相同的区域中。
这可能是显而易见的,但是通过 html 中 div 的顺序,您可以消除 z 轴的使用。如果您希望您的内容是通用的(也适用于其他开发人员),请使用 z 轴,但存储添加图层索引的基线(以便在以有问题的方式使用使用 z 轴的其他代码时可以调整基线)。
Setting the container div relative ought to have prevented that layer-overwrite issue. Try setting the position on the "occluded text" - e.g. if it's currently absolue it will obvious go in the same region as the top left of the relative stuff.
And it's probably obvious but, by the order of divs in the html you can eliminate the use of the z axis. If you want your stuff to be generic (and for other developers too), use the z axis but store a baseline to which you add your layer indices (so that baseline can be tweaked when using other code using z-axis in a problematic way).
使用jCanvas,查看其图层API:http://projects.calebevans.me/jcanvas/docs/layerAPI/
Using jCanvas,see its layer API: http://projects.calebevans.me/jcanvas/docs/layerAPI/