在HTML5中堆叠多个画布

时间:2014-01-04 01:01:18

标签: javascript html5 canvas multiple-instances

我正在尝试使用相互堆叠的四个画布,但除了顶部的内容之外,它们的内容将不会显示。我按顺序将z-index值放到它们中,我希望它们显示,但只有顶部显示内容。他们的位置是绝对的,他们的z索引是1,2,3和4.还有什么能让它们不显示吗?或者,为了能够显示所有内容,我可以堆叠多少幅画?

我有这个:

<div></div>
<canvas id="bg" width="500" height="500"></canvas> <!--z-index:1 -->
<canvas id="lc" width="500" height="500"></canvas> <!--z-index:2 -->
<canvas id="rc" width="500" height="500"></canvas> <!--z-index:3 -->
<canvas id="ch" width="500" height="500"></canvas> <!--z-index:4 -->
<!-- Script that draws image in each canvas with different x and y values -->

问题在于,当我运行该函数时,我绘制的图片只出现一次,这意味着它只在一个画布上绘制...例如,我将使用这样的脚本:

function drawImgs() {
    var bg = document.getElementById('bg').getContext('2d'),
        lc = document.getElementById('lc').getContext('2d'),
        rc = document.getElementById('rc').getContext('2d'),
        ch = document.getElementById('ch').getContext('2d'),
        img = new Image();
    img.src = "image.png";
    bg.drawImage(img,0,0);
    lc.drawImage(img,64,64);
    rc.drawImage(img,128,128);
    ch.drawImage(img,192,192);
}
drawImgs();

它只会在ch画布上绘制图像,格式为X:192,Y:192。这是为什么? 有没有办法防止它或至少确保所有图像都被绘制? 是因为我使用相同的图像还是画布不透明? 您可以查看多少个画布是否有限制?

修改 但是,如果我只有两个画布,则两个图像都会渲染。为什么是这样?如果我将四个画布堆叠在一起,至少可以渲染两个图像吗?

修改 我正在搞乱你从我们那里收到的代码(感谢所有的信息,一切都有帮助),我试着把它放到我的实际项目中(我测试了代码,它在我把它放入我的项目之前工作)但是,一旦我将它放入我的文件中,它就再次停止工作。所以我搞砸了,我注意到当我没有添加CSS使页面很漂亮它会起作用...我一直在搞乱,我发现画布的背景颜色带走了透明度,它是就这样......所以我只是把它放在第一个画布上,bg,因为我的页面是黑色的,我希望画布是白色的。

3 个答案:

答案 0 :(得分:1)

确保使用CSS将每个画布堆叠在彼此之上

canvas{position:absolute;border:1px solid red;}

确保您的图片有时间加载

var img=new Image();
img.onload=function(){
    bg.drawImage(img,0,0);
    lc.drawImage(img,64,64);
    rc.drawImage(img,128,128);
    ch.drawImage(img,192,192);
}
img.src="img.png";

以下是一个例子:

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    #wrapper{position:relative;}
    canvas{position:absolute;border:1px solid red;}
</style>

<script>
window.onload=function(){


    var ctxs=[];
    for(var i=0;i<5;i++){
        ctxs.push(document.getElementById("canvas"+i).getContext("2d"));
        ctxs[i].fillStyle="black";
        ctxs[i].font="12px verdana";
        ctxs[i].fillRect(50,i*30+20,100,20);
        ctxs[i].fillStyle="white";
        ctxs[i].fillText("canvas#"+i,60,i*30+35);
    };

}
</script>

</head>

<body>
    <div id="wrapper">
        <canvas id="canvas0" width=300 height=300></canvas>
        <canvas id="canvas1" width=300 height=300></canvas>
        <canvas id="canvas2" width=300 height=300></canvas>
        <canvas id="canvas3" width=300 height=300></canvas>
        <canvas id="canvas4" width=300 height=300></canvas>
    </div>
</body>
</html>

最后一个想法:你可以快速浏览一下jQuery。它是一个出色的实用程序库,可以很好地解决跨浏览器的不一致问题。它经过了充分测试并广泛使用,因此您的用户可能已将其缓存在其计算机上。

答案 1 :(得分:1)

第一步是将画布包装成容器:

<div id="stack">
    <canvas id="bg" width="500" height="500"></canvas>
    <canvas id="lc" width="500" height="500"></canvas>
    <canvas id="rc" width="500" height="500"></canvas>
    <canvas id="ch" width="500" height="500"></canvas>
<div>

然后正确应用CSS规则:

#stack {
    position:relative;
    }
#stack > canvas {
    position:absolute;
    left:0;
    top:0;
    }
此处不需要

z-index,因为第一个画布将位于底部等。

接下来是实现图像加载器处理程序,因为图像加载是异步的。这就是为什么你的图像没有显示,因为在调用drawImage()之前图像没有完成加载(在代码到达“第四”元素时,图像可能会被加载,具体取决于各种因素,如缓存,系统性能等 - 但这属于“随机结果”类别:

var bg = document.getElementById('bg').getContext('2d'),
    lc = document.getElementById('lc').getContext('2d'),
    rc = document.getElementById('rc').getContext('2d'),
    ch = document.getElementById('ch').getContext('2d'),
    img = new Image();

img.onload = drawImgs;    /// set handler
img.src = "image.png";    /// set url

function drawImgs() {
    /// 'this' is the loaded image
    bg.drawImage(this, 0,0);
    lc.drawImage(this, 64,64);
    rc.drawImage(this, 128,128);
    ch.drawImage(this, 192,192);

    /// continue rest of code here...
}

如果您将脚本放在页面底部,那就是它。如果在标题中将脚本包装在:

window.onload = function() {

    ... code above here...
}

其他注意事项是您的图片正确加载。为此,您可以在图像对象上使用onerroronabort处理程序:

img.onerror = functionToHandleError;
img.onabort = functionToHandleAbort;

也是在设置src属性之前定义的。

答案 2 :(得分:0)

画布可以是透明的;我以前用过这种方法。我提出了一个JSFiddle你可以检查,以确保你的浏览器没有古怪;我使用的是与示例代码相同的方法,只是绘制正方形而不是图像。我认为这个问题是另一回事。

<canvas id="top" height=100 width=100></canvas>
<canvas id="tall" height=100 width=100></canvas>
<canvas id="short" height=100 width=100></canvas>
<canvas id="bottom" height=100 width=100></canvas>

和JS

var top = document.getElementById("top").getContext("2d");
var tall = document.getElementById("tall").getContext("2d");
var short = document.getElementById("short").getContext("2d");
var bottom = document.getElementById("bottom").getContext("2d");

top.fillRect(0,0,10,10);
tall.fillRect(20,20,10,10);
short.fillRect(40,40,10,10);
bottom.fillRect(60,60,10,10);

要进行调试,我会尝试绘制每个画布个体,从HTML中删除其他画布,以确保您的所有引用都正确(看起来像你这样做。)然后,仔细检查你的CSS和z-index确保你没有以某种方式隐藏元素,或者通过不显示它,或者将它的z-index放在另一个对象后面。最后,确保没有其他代码在某处清除您的画布,或者可能覆盖您的图像(如果它使用与您的背景相同的颜色绘制,那么看起来画布是空白的,当它真的充满背景时色。)