简体   繁体   English

如何在画布中模拟z-index

[英]How can I simulate z-index in canvas

I have asked a question before: How can I control z-index of canvas objects? 我之前问了一个问题: 如何控制画布对象的z-index? and we reached to a solution that may not be a good one for complicated situations. 我们找到了一个对复杂情况可能不是一个好的解决方案。

I found that canvas doesn't have a z-index system, but a simple ordered drawing one. 我发现canvas没有z-index系统,而是一个简单的有序绘图系统。 Now there is a new question: how can I simulate z-index system to make this problem fixed in complicated situations? 现在有一个新问题:我如何模拟z-index系统以在复杂情况下解决这个问题?

The good answer can solve a big problem. 好的答案可以解决一个大问题。

It's not that canvas doesn't have a z-index, it's that canvas doesn't keep objects drawn contrary to the HTML page. 并不是画布没有z索引,而是画布不会使对象与HTML页面相反。 It just draws on the pixel matrix. 它只是利用像素矩阵。

There are basically two types of drawing models : 基本上有两种类型的绘图模型:

  • object ones (usually vector) : objects are kept and managed by the engine. 对象(通常是向量):对象由引擎保存和管理。 They can usually be removed or changed. 通常可以删除或更改它们。 They have a z-index 他们有一个z指数
  • bitmap ones : there are no objects. 位图:没有对象。 You just change a pixel matrix 你只需改变一个像素矩阵

The Canvas model is a bitmap one. Canvas模型是位图模型。 To have objects drawn over other ones, you must draw them after . 要将对象绘制在其他对象上,必须在之后绘制它们。 This means you must manage what you draw. 这意味着您必须管理您绘制的内容。

The canvas model is very fast, but if you want a drawing system managing your objects, maybe you need SVG instead. 画布模型速度非常快,但如果您想要一个管理对象的绘图系统,可能需要使用SVG


If you want to use a canvas, then the best is to keep what you draw as objects. 如果你想使用画布,那么最好是将你绘制的内容保留为对象。 Here's an example I just made : I keep a square list and every second I randomize their zindex and redraw them : 这是我刚才做的一个例子:我保留一个正方形列表,每一秒我随机化它们的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);

Demonstration 示范

The idea is that the square array is sorted accordingly to zindex. 这个想法是方形数组根据zindex进行排序。 This could be easily extended to other types of objects. 这可以很容易地扩展到其他类型的对象。

As dystroy has said, z-index is, at its simplest, just an index to tell you in what order to draw things on the canvas, so that they overlap properly. 正如dystroy所说,z-index最简单的只是一个索引来告诉你在画布上绘制东西的顺序,以便它们正确重叠。

If you mean to do more than this, say to replicate the existing workings of a browser, then you would have more work to do. 如果你的意思是做更多的事情,比如复制浏览器的现有工作方式,那么你还有更多的工作要做。 The order in which objects are drawn in a browser is a complicated calculation that is driven by: 在浏览器中绘制对象的顺序是一个复杂的计算,由以下因素驱动:

  1. The DOM tree DOM树
  2. Elements' position attributes 元素的position属性
  3. Elements' z-index attributes 元素的z-index属性

The canonical source to this is the Elaborate description of Stacking Contexts , part of the CSS specification. 对此的规范来源是Stacking Contexts精细描述,这是CSS规范的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM