HTML5 Canvas设置z-index

时间:2012-02-06 19:10:16

标签: javascript html5

是否可以在HTML5画布中设置绘制对象的z-index?

我试图得到它所以一个对象可以在“玩家”面前,另一个对象在“玩家”背后

5 个答案:

答案 0 :(得分:51)

是的......是的。您可以使用合成来"吸引"现有像素。

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>
&#13;
&#13;
&#13;

答案 1 :(得分:4)

首先绘制它背后的东西,然后是东西,然后是其他对象。

要进行命中测试,您可能需要在显示列表上向后迭代,测试每个对象。如果您非常了解对象边界,这将有效。

或者你可能想尝试一些标准的图形技巧,比如将相同的对象绘制到另一个内存中的画布上,每个绘制的对象都有独特的颜色:点击测试,只需检查内存中画布上的像素颜色。整洁; - )

答案 2 :(得分:4)

我找到的解决方案对我有用(并摆脱闪烁,欢呼!)是使用两个画布。 (或更多)

我会假设你正在制作某种类型的游戏(因为你提到了一个玩家)并以此为例。

您可以从窗口的工作方式中获取一个页面,首先将画布作为背景,然后将另一个画布作为播放器画布。您可以将播放器画布标记为“脏”,也可以在更改时将其更改,并在需要时仅重绘已更改的图层。这意味着您只在玩家移动或采取行动时更新第二个画布。

此方法可以更进一步,您可以为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>

答案 3 :(得分:4)

或者您可以简单地使用包含要绘制的对象的数组,然后使用每个子项的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 !

请注意,我没有测试该代码并将其写在我的手机上,因此可能存在拼写错误,但我希望能够理解这一原则。

答案 4 :(得分:1)

很抱歉,但不,画布元素将拥有其z-index,并且在其上绘制的任何内容都将位于该图层上。

如果你在画布上指的是不同的东西,那么是的,绘制的任何东西都是在之前的任何东西之上绘制的。