如何进行多选矩形?
How to make multiple selection rects?
我正在用 EJS
制作一个网站(服务器用 Express
),它会做一些图像处理。我想做一个功能,用户可以 select 他们上传的图像的一部分,当按下保存按钮时, selected 区域的坐标被保存。他们可以根据需要多次这样做。但是,如果他们在再次 select 一个区域时不单击保存按钮,则旧区域将被覆盖。我在 select 时遇到问题 - 矩形坐标不正确并且通常无法正常工作。我目前正在使用 HTML
canvas
来执行此操作,但欢迎提出任何建议。
相关代码如下:
表格(注意是EJS
不是HTML
):
<form id="edit-form" action="/process" method="POST">
<input
type="text"
id="comment-input"
placeholder="Write a comment: "
spellcheck="true"
/>
<button onclick="addComment();" type="button">Add comment</button><br />
<p id="feedback"></p>
<ol id="comments-list"></ol>
<br />
<canvas id="edit-canvas"></canvas>
<br />
<input type="text" name="comments" style="display: none" />
<input type="text" name="image" style="display: none" />
<button type="submit">Submit</button>
</form>
<script src="./js/edit.js"></script>
<script>
imageExport.value = "<%- image %>";
const backgroundImage = new Image();
backgroundImage.src = "/downloads/<%- image %>";
backgroundImage.onload = () => {
editCanvas.width = backgroundImage.width;
editCanvas.height = backgroundImage.height;
ctx.drawImage(backgroundImage, 0, 0);
};
</script>
JavaScript代码:
const editCanvas = document.querySelector("#edit-canvas");
const ctx = editCanvas.getContext("2d");
editCanvas.addEventListener("mousedown", (event) => {
const startCoords = { x: event.offsetX, y: event.offsetY };
// draw rect to mouse x and y
ctx.fillRect(startCoords.x, startCoords.y, event.clientX, event.clientY);
editCanvas.addEventListener("mouseup", (event2) => {
ctx.clearRect(startCoords.x, startCoords.y, event.clientX, event.clientY);
const endCoords = { x: event2.offsetX, y: event2.offsetY };
ctx.fillRect(
startCoords.x,
startCoords.y,
endCoords.x - startCoords.x,
endCoords.y - startCoords.y
);
});
});
您的代码中有几个错误。
(1)
您正在 mousedown
侦听器中添加一个 mouseup
侦听器。这意味着每次有人点击 canvas 它都会创建一个新的监听器,导致 mouseup 监听器被多次触发。
(2)
您只是在 pressing/releasing canvas 上绘制矩形,而不是在用户实际移动鼠标时绘制。
(3)
在回调函数中,您使用事件的 .offsetX
和 .offsetY
属性来访问位置。错了,你需要分别使用 .clientX
和 .clientY
。此外,代码没有考虑 canvas 元素本身在屏幕上的位置,需要从鼠标位置中减去。
如果我们遍历以上所有要点,我们将得出以下结论:
const editCanvas = document.querySelector("#edit-canvas");
const ctx = editCanvas.getContext("2d");
const backgroundImage = new Image();
let painting = false;
backgroundImage.onload = () => {
editCanvas.width = backgroundImage.width;
editCanvas.height = backgroundImage.height;
ctx.drawImage(backgroundImage, 0, 0);
}
backgroundImage.src = "https://picsum.photos/id/237/200/300";
let startCoords, canvasPosition;
editCanvas.addEventListener("mousedown", (event) => {
painting = true;
canvasPosition = editCanvas.getBoundingClientRect();
startCoords = {
x: event.clientX - canvasPosition.left,
y: event.clientY - canvasPosition.top
};
});
editCanvas.addEventListener("mousemove", (event) => {
if (painting) {
canvasPosition = editCanvas.getBoundingClientRect();
let endCoords = {
x: event.clientX - canvasPosition.left,
y: event.clientY - canvasPosition.top
};
ctx.drawImage(backgroundImage, 0, 0);
ctx.fillStyle = 'rgba(255,0,0,0.4)';
ctx.fillRect(
startCoords.x,
startCoords.y,
endCoords.x - startCoords.x,
endCoords.y - startCoords.y
);
}
});
editCanvas.addEventListener("mouseup", () => {
painting = false;
});
<form id="edit-form" action="/process" method="POST">
<input type="text" id="comment-input" placeholder="Write a comment: " spellcheck="true" />
<button onclick="addComment();" type="button">Add comment</button><br />
<p id="feedback"></p>
<ol id="comments-list"></ol>
<br />
<canvas id="edit-canvas"></canvas>
<br />
<input type="text" name="comments" style="display: none" />
<input type="text" name="image" style="display: none" />
<button type="submit">Submit</button>
</form>
我正在用 EJS
制作一个网站(服务器用 Express
),它会做一些图像处理。我想做一个功能,用户可以 select 他们上传的图像的一部分,当按下保存按钮时, selected 区域的坐标被保存。他们可以根据需要多次这样做。但是,如果他们在再次 select 一个区域时不单击保存按钮,则旧区域将被覆盖。我在 select 时遇到问题 - 矩形坐标不正确并且通常无法正常工作。我目前正在使用 HTML
canvas
来执行此操作,但欢迎提出任何建议。
相关代码如下:
表格(注意是EJS
不是HTML
):
<form id="edit-form" action="/process" method="POST">
<input
type="text"
id="comment-input"
placeholder="Write a comment: "
spellcheck="true"
/>
<button onclick="addComment();" type="button">Add comment</button><br />
<p id="feedback"></p>
<ol id="comments-list"></ol>
<br />
<canvas id="edit-canvas"></canvas>
<br />
<input type="text" name="comments" style="display: none" />
<input type="text" name="image" style="display: none" />
<button type="submit">Submit</button>
</form>
<script src="./js/edit.js"></script>
<script>
imageExport.value = "<%- image %>";
const backgroundImage = new Image();
backgroundImage.src = "/downloads/<%- image %>";
backgroundImage.onload = () => {
editCanvas.width = backgroundImage.width;
editCanvas.height = backgroundImage.height;
ctx.drawImage(backgroundImage, 0, 0);
};
</script>
JavaScript代码:
const editCanvas = document.querySelector("#edit-canvas");
const ctx = editCanvas.getContext("2d");
editCanvas.addEventListener("mousedown", (event) => {
const startCoords = { x: event.offsetX, y: event.offsetY };
// draw rect to mouse x and y
ctx.fillRect(startCoords.x, startCoords.y, event.clientX, event.clientY);
editCanvas.addEventListener("mouseup", (event2) => {
ctx.clearRect(startCoords.x, startCoords.y, event.clientX, event.clientY);
const endCoords = { x: event2.offsetX, y: event2.offsetY };
ctx.fillRect(
startCoords.x,
startCoords.y,
endCoords.x - startCoords.x,
endCoords.y - startCoords.y
);
});
});
您的代码中有几个错误。
(1)
您正在 mousedown
侦听器中添加一个 mouseup
侦听器。这意味着每次有人点击 canvas 它都会创建一个新的监听器,导致 mouseup 监听器被多次触发。
(2)
您只是在 pressing/releasing canvas 上绘制矩形,而不是在用户实际移动鼠标时绘制。
(3)
在回调函数中,您使用事件的 .offsetX
和 .offsetY
属性来访问位置。错了,你需要分别使用 .clientX
和 .clientY
。此外,代码没有考虑 canvas 元素本身在屏幕上的位置,需要从鼠标位置中减去。
如果我们遍历以上所有要点,我们将得出以下结论:
const editCanvas = document.querySelector("#edit-canvas");
const ctx = editCanvas.getContext("2d");
const backgroundImage = new Image();
let painting = false;
backgroundImage.onload = () => {
editCanvas.width = backgroundImage.width;
editCanvas.height = backgroundImage.height;
ctx.drawImage(backgroundImage, 0, 0);
}
backgroundImage.src = "https://picsum.photos/id/237/200/300";
let startCoords, canvasPosition;
editCanvas.addEventListener("mousedown", (event) => {
painting = true;
canvasPosition = editCanvas.getBoundingClientRect();
startCoords = {
x: event.clientX - canvasPosition.left,
y: event.clientY - canvasPosition.top
};
});
editCanvas.addEventListener("mousemove", (event) => {
if (painting) {
canvasPosition = editCanvas.getBoundingClientRect();
let endCoords = {
x: event.clientX - canvasPosition.left,
y: event.clientY - canvasPosition.top
};
ctx.drawImage(backgroundImage, 0, 0);
ctx.fillStyle = 'rgba(255,0,0,0.4)';
ctx.fillRect(
startCoords.x,
startCoords.y,
endCoords.x - startCoords.x,
endCoords.y - startCoords.y
);
}
});
editCanvas.addEventListener("mouseup", () => {
painting = false;
});
<form id="edit-form" action="/process" method="POST">
<input type="text" id="comment-input" placeholder="Write a comment: " spellcheck="true" />
<button onclick="addComment();" type="button">Add comment</button><br />
<p id="feedback"></p>
<ol id="comments-list"></ol>
<br />
<canvas id="edit-canvas"></canvas>
<br />
<input type="text" name="comments" style="display: none" />
<input type="text" name="image" style="display: none" />
<button type="submit">Submit</button>
</form>