HTML5 Canvas set z-index - PullRequest
       5

HTML5 Canvas set z-index

37 голосов
/ 06 февраля 2012

Можно ли установить z-индекс нарисованного объекта на холсте HTML5?

Я пытаюсь получить его, чтобы один объект мог находиться перед «игроком», а другой объект - за «игроком»

Ответы [ 5 ]

51 голосов
/ 26 сентября 2014

Да .. вроде да. Вы можете использовать композитинг, чтобы «рисовать» за существующими пикселями.

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>
5 голосов
/ 07 февраля 2012

Сначала нарисуйте вещи позади него, затем вещь, затем другие объекты.

Чтобы выполнить тестирование попаданий, вам может потребоваться выполнить итерацию по списку отображения, проверяя каждый объект. Это будет работать, если вы действительно хорошо знаете границы объекта.

Или вы можете попробовать некоторые стандартные графические приемы, такие как рисование тех же объектов на другом холсте в памяти с уникальными цветами для каждого нарисованного объекта: чтобы проверить это, просто проверьте цвет пикселей на холсте в памяти. Аккуратный; -)

4 голосов
/ 26 августа 2016

Или вы можете просто использовать массив, содержащий ваши объекты для рисования, а затем отсортировать этот массив, используя свойство zIndex каждого дочернего элемента.Затем вы выполняете итерацию этого массива и рисуете.

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 голосов
/ 26 сентября 2014

Решение, которое я нашел, работает для меня (и избавляется от мерцания, ура!) - это использование двух холстов. (или больше)

Я предполагаю, что вы делаете какую-то игру (поскольку вы упоминаете игрока), и используйте ее в качестве примера.

Вы можете взять страницу из того, как работает 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>
1 голос
/ 06 февраля 2012

Извините, но нет, элемент canvas будет иметь свой z-индекс, и все, что нарисовано на нем, будет на этом слое.

Если вы имеете в виду разные вещи на холсте, то да, все, что нарисовано, нарисовано поверх того, что было раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...