如何将多个图像绘制到单个canvas?
How to draw multiple images to a single canvas?
我正在制作一个允许用户绘制草图并指定其位置和大小的网站;然后,我将它们保存到数据库中。在不同的路线中,我想加载这些图像并将它们显示在单个 canvas.
上
我为此使用了 drawImage
函数,但实际情况是第二张图像绘制在第一张图像上。就像下图中的两个草图 circle
和 triangle
:
以下是我在 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()
,例如 img
、tx
、ty
、tw
、th
,它们都具有所需的值,但仍然在 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);
};
});
}
我正在制作一个允许用户绘制草图并指定其位置和大小的网站;然后,我将它们保存到数据库中。在不同的路线中,我想加载这些图像并将它们显示在单个 canvas.
上我为此使用了 drawImage
函数,但实际情况是第二张图像绘制在第一张图像上。就像下图中的两个草图 circle
和 triangle
:
以下是我在 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()
,例如 img
、tx
、ty
、tw
、th
,它们都具有所需的值,但仍然在 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);
};
});
}