Подтвердить что ты не робот

HTML5 Canvas set z-index

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

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

4b9b3361

Ответ 1

Да, да. Вы можете использовать композицию для "затягивания" существующих пикселей.

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>

Ответ 2

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

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

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

Этот метод можно сделать еще дальше, и вы можете добавить третий холст для 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

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

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

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

Ответ 4

Или вы можете просто использовать массив, содержащий ваши объекты для рисования, затем сортировать этот массив, используя свойство 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 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 - b;
});

// 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 !

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

Ответ 5

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

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