【问题标题】:Issue with Layering Canvases using z-index使用 z-index 分层画布的问题
【发布时间】:2018-11-05 23:16:54
【问题描述】:

我在这里查看了许多画布 z-index 帖子,包括:

HTML5 Canvas layer issue
Multi Layer Canvas HTML5
html5 - canvas element - Multiple layers

但我没有找到问题的答案。

我试图简单地将一个画布直接放在另一个画布后面。当用户点击画布时,它会改变堆叠顺序。但是,画布不是在彼此的前后,而是可以看到,一个在上面,一个在它下面(不是在它后面)(参见https://imgur.com/a/BcUNy)。

HTML 和 CSS:

<div id="preview" style="visibility:hidden;">
  <canvas id="cOriginal" width="2" height="1" onclick="clickCompare()" style="position:relative; z-index:2; border-style:solid; border-color: #C0C0C0 #C0C0C0 #606060 #606060;"></canvas>
  <canvas id="cPreview" width="2" height="1" onclick="clickCompare()" style="position:relative; z-index:1; border-style:solid; border-color: #C0C0C0 #C0C0C0 #606060 #606060;"></canvas>    
  <canvas id="cSave" width="2" height="1" style="position:relative; z-index:0; border-style:solid; border-color: #C0C0C0 #C0C0C0 #606060 #606060;"></canvas>
</div>      

非常感谢!

编辑:更新我的问题以显示当前问题。

HTML:

<div id="preview" style="visibility:hidden; position:relative;">
  <canvas id="cOriginal" width="2" height="1" onclick="clickCompare()" style="position:absolute; z-index:2; border-style:solid; border-color: #C0C0C0 #C0C0C0 #606060 #606060;"></canvas>
  <canvas id="cPreview" width="2" height="1" onclick="clickCompare()" style="position:absolute; z-index:1; border-style:solid; border-color: #C0C0C0 #C0C0C0 #606060 #606060;"></canvas>    
  <canvas id="cSave" width="2" height="1" style="position:absolute; z-index:0; border-style:solid; border-color: #C0C0C0 #C0C0C0 #606060 #606060;"></canvas>
</div>

CSS(居中代码):

<style>
  #cOriginal, #cPreview, #cSave { max-width: 100%; display: block; margin: auto; left: 0; right: 0; margin-left: auto; margin-right: auto; }     
</style> 

画布现在分层并居中。但是画布后面的一切都坏了。见https://imgur.com/AHG59zd。谢谢!

【问题讨论】:

  • 为什么不只使用一个画布并按照您想要的顺序绘制图像。它更快(无需强制回流和不受控制的合成)并且代码更简单。
  • 感谢您的评论,但这在这里不会有效。该代码将用于显示原始图像与编辑后的图像。编辑代码遍历图像以读取它,对 R、G、B、A 数组进行更改,然后再次迭代以重绘图像。在大图像上,这可能很耗时。如果图像可以绘制一次然后简单地交换 z-index 顺序,那么复制所有这些是没有意义的。
  • 只需将编辑后的图像保留为屏幕外画布即可。总体而言,您将获得性能提升。您可以像绘制图像一样将画布绘制到画布上。 ctx.drawImage(canvas2,0,0)
  • @Blindman67 这很有趣,感谢您指出。将“canvas2”保持在屏幕之外的首选方法是什么?

标签: html canvas z-index


【解决方案1】:

第一次回答 SO,但我相信我已经回答了你的问题。

我将 HTML 和 JavaScript 重新编写为尽可能简单,因为您的问题似乎是这一切的根源,在更改画布分层方面寻求帮助,所以我尽可能简单地做到了,在这里是代码,后面是codepen的链接:

<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Canvas Layering</title>
</head>

<body>
    <div style="position: relative;">
        <canvas id="layer1" width="100" height="100" 
            style="position: absolute; left: 0; top: 0; z-index: 0; background-image: url(https://static.pexels.com/photos/158780/leaf-nature-green-spring-158780.jpeg);" onclick="ChangePicture(1)"></canvas>
        <canvas id="layer2" width="100" height="100" 
            style="position: absolute; left: 0; top: 0; z-index: 1; background-image: url(https://static.pexels.com/photos/54320/rose-roses-flowers-red-54320.jpeg);" onclick="ChangePicture(2)"></canvas>
        <canvas id="layer3" width="100" height="100" 
            style="position: absolute; left: 0; top: 0; z-index: 2; background-image: url(https://static.pexels.com/photos/5412/water-blue-ocean.jpg);" onclick="ChangePicture(3)"></canvas>
    </div>
</body>

<script>

    function ChangePicture(layerNumber) {
        if (layerNumber === 1) {
            document.getElementById("layer1").style.zIndex = "0";
            document.getElementById("layer2").style.zIndex = "2";
            document.getElementById("layer3").style.zIndex = "1";
        } else if (layerNumber === 2) {
            document.getElementById("layer1").style.zIndex = "1";
            document.getElementById("layer2").style.zIndex = "0";
            document.getElementById("layer3").style.zIndex = "2";
        } else if (layerNumber === 3) {
            document.getElementById("layer1").style.zIndex = "2";
            document.getElementById("layer2").style.zIndex = "1";
            document.getElementById("layer3").style.zIndex = "0";
        } else {
            console.log("Failed.");
        }
    }

</script>

</html>

https://codepen.io/levi_blodgett/pen/KQyWoR

如果您想更改默认图片的开头,只需更改 html 中样式的 z-index 即可。

【讨论】:

  • 这确实成功地将 3 幅画布彼此叠放。不幸的是,它们位于屏幕的最左侧,而不是居中。但是,我想我可能已经解决了。我会告诉你。谢谢!
  • 好的,这样就解决了分层问题,唯一的问题是所有东西都位于左侧,我用 CSS 代码解决了这个问题。唯一的问题是,页面停在画布的底部,出现在画布下方的项目出现在它的后面。如果您(或任何人)有解决该问题的建议,请告诉我!
  • 请看一下imgur.com/AHG59zd,它会比我解释得更好。简而言之,图像下方的控件,我怀疑页脚也是如此,现在位于画布后面。
  • 我在查看您的更新后明白了您的意思,您要做的是在下面给它一个边距,因为它是一个绝对位置,这意味着它忽略了其他元素及其间距,但是,您可以做的是增加它周围的边距以适当地间隔它,即: position: absolute;左:50%;顶部:500 像素;这样您就可以适当地分隔所有内容。
  • 所以我的代码并没有什么问题,这只是必须对图层使用“绝对”的结果吗?另外,我现在不需要重新定位画布下方的所有内容吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 2015-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多