画布没有合并,导致只显示背景图像

时间:2016-11-24 04:54:36

标签: javascript html html5 canvas

我创建了2个画布,加载了两个不同的图像,我想合并两个画布,然后将其显示为<div id="test"></div>标记中的图像。

这是我的代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"> 
    <title>canvas to image</title>
</head>
<body>
<div>
    <canvas id="card_canvas" width="800" height="500"></canvas>
    <canvas id="card_canvas2" width="800" height="500"></canvas>
</div>
<div id="test"></div>
<button onclick="canvasToImage()">canvas to image</button>
<script>
    var img1 = new Image();
        img1.src = "images/img1.jpg";
    var cuimg;
    function canvasToImage(){
        var canvass1 = document.getElementById("card_canvas");
        var canvass2 = document.getElementById("card_canvas2");
        var ctx1 = canvass1.getContext('2d');
        var ctx2 = canvass2.getContext('2d');
        ctx1.drawImage(img1, 0, 0);
        cuimg = new Image();
        cuimg.onload = function(){
            ctx2.drawImage(cuimg, 7, 92);
        }
        cuimg.src = "images/img2.jpg";
        ctx1.drawImage(canvass2, 0, 0);
        var imgdata = canvass1.toDataURL('image/png');
        var mergeimg = document.createElement("img");
        mergeimg.src = imgdata;
        document.getElementById("test").appendChild(mergeimg);
    }
</script>
</body>
</html>

这是img1.jpg:

img1.jpg

这是img2.jpg:

img2.jpg

此代码最终仅显示背景图像:

result

我期待:

expected

2 个答案:

答案 0 :(得分:0)

只需在canvas2上设置以下样式即可实现:

<canvas id="card_canvas2" style="position:absolute; left:0px; top:0px;"></canvas>

https://jsfiddle.net/jkjqd7gz/

答案 1 :(得分:0)

我一直在调整你的代码,我想我已经找到了问题。 javascript有一个有趣的执行顺序,有时大多数人都不知道。你的onload lambda函数导致你遇到的一些问题。基本上,你需要移动你的ctx1.drawImage(canvass2,0,0);你的lambda函数里面的行就在ctx2.drawImage之后(cuimg,7,92);要了解我的意思,打开代码并按两次“画布到图像”按钮。第一次填充两个画布,第二次将canvass2的内容放到canvass1上。我可以准确地解释在执行顺序方面发生了什么,但是解释涉及关于并行性,交换缓冲区和竞争条件的一些难以理解的概念。

简而言之,无论你调用ctx2.drawImage的函数是什么,你都需要用ctx1.drawImage跟随它。老实说,制作合成图像的最佳方法是创建一个精灵类,如果需要,可以存储图像,位置和图层信息。然后使用动态数组来存储精灵。每次在绘制画布之前总是清除画布并循环遍历阵列的内容,在各自的画布上按层次顺序绘制每个精灵。最后,我将使用一组函数来填充画布,使用第二组函数来合并它们。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"> 
    <title>canvas to image</title>
</head>
<body>
<div>
    <canvas id="card_canvas" width="800" height="500"></canvas>
    <canvas id="card_canvas2" width="800" height="500"></canvas>
</div>
<div id="test"></div>
<button onclick="popCanvas()">Populate Canvasses</button>
<button onclick="canvasToImage()">Canvas Combine</button>
<script>
    var img1 = new Image();
        img1.src = "images/img1.jpg";
    var cuimg = new Image();
    var canvass1 = document.getElementById("card_canvas");
    var canvass2 = document.getElementById("card_canvas2");
    function popCanvas(){
        var ctx1 = canvass1.getContext('2d');
        var ctx2 = canvass2.getContext('2d');
        ctx1.clear()
        ctx2.clear()
        ctx1.drawImage(img1, 0, 0);
        cuimg.onload = function(){
            ctx2.drawImage(cuimg, 7, 92);
        }
        cuimg.src = "images/img2.jpg";
    }
    function canvasToImage(){
        var ctx1 = canvass1.getContext('2d');
        var ctx2 = canvass2.getContext('2d');
        ctx1.drawImage(canvass2, 0, 0);
        var imgdata = canvass1.toDataURL('image/png');
        var mergeimg = document.createElement("img");
        mergeimg.src = imgdata;
        document.getElementById("test").appendChild(mergeimg);
    }
</script>
</body>
</html>