6

我之前问过一个问题:如何控制画布对象的z-index?我们达成的解决方案可能不适用于复杂的情况。

我发现画布没有 z-index 系统,而是一个简单的有序绘图系统。现在有一个新问题:如何模拟z-index系统来解决这个问题在复杂的情况下?

好的答案可以解决一个大问题。

4

2 回答 2

9

并不是canvas 没有z-index,而是canvas 不会保留与HTML 页面相反的对象。它只是在像素矩阵上绘制。

基本上有两种类型的绘图模型:

  • 对象(通常是向量):对象由引擎保存和管理。它们通常可以删除或更改。他们有一个 z-index
  • 位图:没有对象。你只需改变一个像素矩阵

Canvas 模型是位图模型。要将对象绘制在其他对象之上,您必须在 之后绘制它们。这意味着您必须管理您绘制的内容。

画布模型非常快,但是如果您想要一个绘图系统来管理您的对象,也许您需要SVG来代替。


如果您想使用画布,那么最好将您绘制的内容保留为对象。这是我刚刚制作的一个示例:我保留了一个方形列表,并且每一秒我都会随机化它们的 zindex 并重新绘制它们:

var c = document.getElementById('c').getContext('2d');
function Square(x, y, s, color) {
   this.x = x; this.y = y; this.s = s; this.color = color;
   this.zindex=0;
}
Square.prototype.draw = function(c) {
  c.fillStyle = this.color;
  c.fillRect(this.x, this.y, this.s, this.s);  
}
var squares = [
  new Square(10, 10, 50, 'blue'), new Square(40, 10, 40, 'red'), new Square(30, 50, 30, 'green'),
  new Square(60, 30, 40, '#111'), new Square(0, 30, 20, '#444'), new Square(70, 00, 40, '#999')
];

function draw() {
  c.fillStyle = "white";
  c.fillRect(0, 0, 1000, 500);
  for (var i=0; i<squares.length; i++) squares[i].draw(c);
}
setInterval(function(){
  // give all squares a random z-index
  squares.forEach(function(v){v.zindex=Math.random()});
  // sort the list accordingly to zindex
  squares.sort(function(a,b){return a.zindex-b.zindex});
  draw();
}, 1000);

示范

这个想法是方形数组根据zindex进行排序。这可以很容易地扩展到其他类型的对象。

于 2013-01-11T07:03:59.350 回答
1

正如dystroy所说,最简单的z-index只是一个索引,告诉你在画布上以什么顺序绘制东西,以便它们正确重叠。

如果您打算做更多的事情,比如复制浏览器的现有工作原理,那么您将有更多的工作要做。在浏览器中绘制对象的顺序是一个复杂的计算,由以下因素驱动:

  1. DOM 树
  2. 元素的position属性
  3. 元素的z-index属性

规范的来源是Stacking Contexts 的详细描述,它是 CSS 规范的一部分。

于 2013-01-11T07:13:32.513 回答