是否可以在 HTML5 画布中设置绘制对象的 z-index?
我试图得到它,所以一个物体可以在“玩家”的前面,另一个物体在“玩家”的后面
是否可以在 HTML5 画布中设置绘制对象的 z-index?
我试图得到它,所以一个物体可以在“玩家”的前面,另一个物体在“玩家”的后面
是的......有点是的。您可以使用globalCompositeOperation来“绘制”现有像素。
ctx.globalCompositeOperation='destination-over';
这是一个示例和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cx=100;
drawCircle()
cx+=20;
ctx.globalCompositeOperation='destination-over';
$("#test").click(function(){
drawCircle();
cx+=20;
});
function drawCircle(){
ctx.beginPath();
ctx.arc(cx,150,20,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle=randomColor();
ctx.fill();
}
function randomColor(){
return('#'+Math.floor(Math.random()*16777215).toString(16));
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="test">Draw new circle behind.</button><br>
<canvas id="canvas" width=300 height=300></canvas>
只需先画出它背后的东西,然后是东西,然后是其他物体。
要进行命中测试,您可能需要向后遍历显示列表,测试每个对象。如果您非常了解对象边界,这将起作用。
或者您可能想尝试一些标准的图形技巧,例如将相同的对象绘制到另一个内存画布上,并为每个绘制的对象使用独特的颜色:要进行命中测试,只需检查内存画布上的像素颜色。整洁的 ;-)
或者您可以简单地使用包含要绘制的对象的数组,然后使用zIndex
每个子项的属性对该数组进行排序。然后你 jist 迭代该数组并绘制。
var canvas = document.querySelector('#game-canvas');
var ctx = canvas.getContext('2d');
// Define our shape "class".
var Shape = function (x, y, z, width, height) {
this.x = x;
this.y = y;
this.zIndex = z;
this.width = width;
this.height = height;
};
// Define the shape draw function.
Shape.prototype.draw = function () {
ctx.fillStyle = 'lime';
ctx.fillRect(this.x, this.y, this.width, this.height);
};
// let's store the objects to be drawn.
var objects = [
new Shape(10, 10, 0, 30, 30), // should be drawn first.
new Shape(50, 10, 2, 30, 30), // should be drawn third.
new Shape(90, 10, 1, 30, 30) // should be drawn second.
];
// For performance reasons, we will first map to a temp array, sort and map the temp array to the objects array.
var map = objects.map(function (el, index) {
return { index : index, value : el.zIndex };
});
// Now we need to sort the array by z index.
map.sort(function (a, b) {
return a.value - b.value;
});
// We finaly rebuilt our sorted objects array.
var objectsSorted = map.map(function (el) {
return objects[el.index];
});
// Now that objects are sorted, we can iterate to draw them.
for (var i = 0; i < objectsSorted.length; i++) {
objectsSorted[i].draw();
}
// Enjoy !
请注意,我没有测试该代码并在我的手机上编写它,所以可能有错别字,但我希望这样应该可以理解原理。
我发现对我有用的解决方案(并摆脱闪烁,万岁!)是使用两个画布。(或者更多)
我假设您正在制作某种游戏(因为您提到了玩家)并以此为例。
您可以从 Windows 的工作方式中获取一个页面,然后将一个画布作为背景,然后将另一个画布作为您的播放器画布。您可以将播放器画布标记为“脏”或在更改时进行更改,并且仅在需要时重新绘制更改后的图层。这意味着您只在玩家移动或采取行动时更新第二个画布。
这种方法可以走得更远,你可以为 HUD 添加第三个画布,上面有游戏统计数据,只有在玩家的统计数据发生变化时才会改变。
html 可能如下所示:
<canvas id="background-canvas" height="500" width="1000" style="border:1px solid #000000;"></canvas>
<canvas id="player-canvas" height="500" width="1000" style="border:1px solid #000000;"></canvas>
<canvas id="hud-canvas" height="500" width="1000" style="border:1px solid #000000;"></canvas>
抱歉,但不,画布元素将有其 z-index,并且在其上绘制的任何内容都将在该图层上。
如果您指的是画布上的不同事物,那么是的,绘制的任何内容都是在之前绘制的内容之上绘制的。