如何将多个图像绘制到单个canvas?

How to draw multiple images to a single canvas?

我正在制作一个允许用户绘制草图并指定其位置和大小的网站;然后,我将它们保存到数据库中。在不同的路线中,我想加载这些图像并将它们显示在单个 canvas.

我为此使用了 drawImage 函数,但实际情况是第二张图像绘制在第一张图像上。就像下图中的两个草图 circletriangle:

以下是我在 canvas 上绘制图像的方法:

var canvas = document.getElementById("paint");    
var ctx = canvas.getContext("2d");
function loadImages(data, targetX, targetY, targetWidth, targetHeight) {

    data = data.replace(/'/g, '"');
    targetX = targetX.replace(/'/g, '"');
    targetY = targetY.replace(/'/g, '"');
    targetWidth = targetWidth.replace(/'/g, '"');
    targetHeight = targetHeight.replace(/'/g, '"');

    data = JSON.parse(data);
    targetX = JSON.parse(targetX);
    targetY = JSON.parse(targetY);
    targetWidth = JSON.parse(targetWidth);
    targetHeight = JSON.parse(targetHeight);

    for(var i = 0; i < data.length; i++) {
        var img = new Image();
        var tx = parseInt(targetX[i]);
        var ty = parseInt(targetY[i]);
        var tw = parseInt(targetWidth[i]);
        var th = parseInt(targetHeight[i]);
        img.src = data[i];
        img.onload = function() {
            ctx.drawImage(this, tx, ty, tw, th);
        };

        
    }

}

这里的字符串格式化将从数据库(通过Flask)获取的数据转换为JavaScript数组。我在所有变量上使用了 console.log(),例如 imgtxtytwth,它们都具有所需的值,但仍然在 canvas 上,它们没有正确绘制,所以我无法缩小问题范围。

下面是我如何调用 HTML 文件中的函数:

{% block content %}
{% if files %}

<button id="show" onclick="loadImages(`{{ data }}`, `{{ targetX }}`, `{{ targetY }}`, `{{ sizeX }}`, `{{ sizeY }}`)">View</button>

<canvas id="paint" width="512" height="512" style="border: 5px solid #000000;"></canvas>
{% endif %}
    
<script src=" {{ url_for('static', filename='edit.js') }}"></script>

{% endblock %}

您正在同步循环中执行异步操作。试试这个..

var canvas = document.getElementById("paint");
var ctx = canvas.getContext("2d");

async function loadImages(data, targetX, targetY, targetWidth, targetHeight) {
  var images = {};
  data = data.replace(/'/g, '"');
  targetX = targetX.replace(/'/g, '"');
  targetY = targetY.replace(/'/g, '"');
  targetWidth = targetWidth.replace(/'/g, '"');
  targetHeight = targetHeight.replace(/'/g, '"');

  data = JSON.parse(data);
  targetX = JSON.parse(targetX);
  targetY = JSON.parse(targetY);
  targetWidth = JSON.parse(targetWidth);
  targetHeight = JSON.parse(targetHeight);

  for (var i = 0; i < data.length; i++) {
    var tx = parseInt(targetX[i]);
    var ty = parseInt(targetY[i]);
    var tw = parseInt(targetWidth[i]);
    var th = parseInt(targetHeight[i]);
    var img = await loadImage(data[i]);
    ctx.drawImage(img, tx, ty, tw, th);
  }

}

function loadImage(src){
  return new Promise(done=>{
    var img = new Image();
    img.src = src;
    img.onload = function() {
      done(img);
    };
  });
}