我之前问过一个问题:如何控制画布对象的z-index?我们达成的解决方案可能不适用于复杂的情况。
我发现画布没有 z-index 系统,而是一个简单的有序绘图系统。现在有一个新问题:如何模拟z-index系统来解决这个问题在复杂的情况下?
好的答案可以解决一个大问题。
我之前问过一个问题:如何控制画布对象的z-index?我们达成的解决方案可能不适用于复杂的情况。
我发现画布没有 z-index 系统,而是一个简单的有序绘图系统。现在有一个新问题:如何模拟z-index系统来解决这个问题在复杂的情况下?
好的答案可以解决一个大问题。
并不是canvas 没有z-index,而是canvas 不会保留与HTML 页面相反的对象。它只是在像素矩阵上绘制。
基本上有两种类型的绘图模型:
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进行排序。这可以很容易地扩展到其他类型的对象。
正如dystroy所说,最简单的z-index只是一个索引,告诉你在画布上以什么顺序绘制东西,以便它们正确重叠。
如果您打算做更多的事情,比如复制浏览器的现有工作原理,那么您将有更多的工作要做。在浏览器中绘制对象的顺序是一个复杂的计算,由以下因素驱动:
position
属性z-index
属性规范的来源是Stacking Contexts 的详细描述,它是 CSS 规范的一部分。