【问题标题】:How can I control z-index of canvas objects?如何控制画布对象的 z-index?
【发布时间】:2012-12-24 09:56:03
【问题描述】:

当我在画布中绘制一些对象时,有时新对象会放在旧对象之下。例如,我在画布上添加一些图像,然后画一条线。当我运行代码时,图像是最重要的。我在网上搜索解决方案。但是没有一个直接的解决方案。 :( 在某些情况下,它被视为一个错误!在资源管理器中。如何控制 z-index?

编辑:这是我的代码

<img id="black_checkers_piece" src="egsdk/BlackCheckersPiece.png" style="display: none;">
<canvas id="c1" style="border:1px solid #998800"></canvas>
<script type="text/javascript">
var canvasID = document.getElementById('c1');
var ctx = canvasID.getContext('2d');
var img = new Image();
img.src = document.getElementById('black_checkers_piece').src;
img.onload = function(){
ctx.drawImage(img, 10, 10, 32, 32);
}
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(0, 0);
ctx.lineTo(50, 50);
ctx.stroke();
</script>

【问题讨论】:

标签: javascript html canvas


【解决方案1】:

我一直在使用 fabric.js,它有一些你可能会觉得有用的功能。虽然本身不​​是 z-index,但它可以设置背景或覆盖 - 下面是在 http://fabricjs.com/customization/ 上找到的示例

var canvas = new fabric.Canvas('c13'); canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 100, left: 100 })); canvas.setOverlayImage('../assets/jail_cell_bars.png', canvas.renderAll.bind(canvas)); this.__canvases.push(canvas);

【讨论】:

  • 不错的 JS 库。谢谢
【解决方案2】:

您很可能在绘制图像之前等待图像加载。

此外,您可能会尽快画线。

您需要等待所有图像加载完毕,然后按照您想要的顺序(从最远的 z 顺序到最近)绘制所有内容。在加载所有图像之前不要绘制任何东西,否则您的 z 顺序将不正确。

如果您想在加载所有图像之前在屏幕上显示项目,则必须在每次加载图像时重绘所有内容,而不仅仅是绘制那张图像。

这是一个示例,我在其中绘制了 3 个对象:一个圆圈、一个图像和一个窗口。无论图像是否加载,我都会立即绘制它们,但是一旦加载图像,我会再次绘制 所有 以确保图像正确位于其他两个对象之间:

http://jsfiddle.net/U5bXf/32/

简写相关代码(以防 jsfiddle 宕机)为:

var img = new Image()
img.onload = function() {
  draw()
};
img.src = "http://placekitten.com/100/140";

draw();

function draw() {
// object one

// Now we'll draw the image in between, if its loaded
ctx.drawImage(img, 100, 30);

// object two
}

此行下面的代码是对 cme​​ts 的响应

您已经发布了代码,但您会注意到您在 onload 函数中绘制的唯一内容就是图像。

onload 函数通常发生在 其他绘图命令之后(除非页面已经加载,否则可能是其中之一)。您需要将所有绘图代码移动到 onload 函数中,或者创建自己的绘图函数来加载所有内容。例如:

<img id="black_checkers_piece" src="egsdk/BlackCheckersPiece.png" style="display: none;">
<canvas id="c1" style="border:1px solid #998800"></canvas>
<script type="text/javascript">
var canvasID = document.getElementById('c1');
var ctx = canvasID.getContext('2d');
var img = new Image();
img.src = document.getElementById('black_checkers_piece').src;
img.onload = function(){
  // assuming we want the image drawn before the line:
  ctx.drawImage(img, 10, 10, 32, 32);

  ctx.beginPath();
  ctx.strokeStyle = 'red';
  ctx.moveTo(0, 0);
  ctx.lineTo(50, 50);
  ctx.stroke();
}

【讨论】:

  • 我怀疑你做错了什么,你的代码是完美的候选者。我更新了我的答案,展示了你如何使用你的代码来做到这一点
  • 谢谢。那行得通,我目前的问题得到了解决。但是,如果场景中的对象越来越多,例如游戏,那将是地狱,不是吗?以后有没有更好的维护方式?
  • 嗯,是的,但你需要更多的组织。也许今晚晚些时候我可以创建一个更通用的示例
【解决方案3】:

Canvas 没有任何“z-index”的概念。画布中没有对象 - 画布只是位图,只是像素。

您确定您是在画布上绘制线条和图像,而不仅仅是创建新元素(如 img 元素?)。

如果是,请检查调用诸如填充() 和描边() 等绘图方法的顺序。在您执行此操作之前不会真正绘制形状(无论您在哪里调用 moveTo 和 lineTo)。

【讨论】:

  • 我通过添加示例来编辑问题。订单是一回事,显示图像是另一回事!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-26
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 2021-03-02
相关资源
最近更新 更多