【问题标题】:How to make multiple selection rects?如何进行多选矩形?
【发布时间】:2022-01-13 19:33:26
【问题描述】:

我正在使用EJS(使用Express 的服务器)创建一个网站,它会进行一些图像处理。我想制作一个功能,用户可以选择他们上传的图像的一部分,当按下保存按钮时,保存所选区域的坐标。他们可以根据需要多次这样做。但是,如果他们在再次选择区域时没有单击保存按钮,则旧的区域将被覆盖。我选择时遇到问题 - 矩形不在正确的坐标处,并且通常无法正常工作。我目前正在使用 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
        );
    });
});

【问题讨论】:

    标签: javascript html html5-canvas ejs


    【解决方案1】:

    您的代码中有几个错误。

    (1)

    您在 mousedown 监听器中添加了一个 mouseup 监听器。这意味着每次有人单击画布时,它都会创建一个新的侦听器,从而导致 mouseup 侦听器被多次触发。

    (2)

    您只是在按下/释放画布时绘制矩形,而不是在用户实际移动鼠标时绘制矩形。

    (3)

    在回调函数中,您使用事件的.offsetX.offsetY 属性来访问位置。错了,你需要分别使用.clientX.clientY。此外,代码没有考虑画布元素本身在屏幕上的位置,需要从鼠标位置中减去。

    如果我们回顾以上所有要点,我们将得出以下结论:

    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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-09
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 2020-10-28
      • 2019-04-02
      相关资源
      最近更新 更多