如何在HTML canvas元素外部绘制?

问题描述 投票:5回答:3

我有一个HTML canvas元素,并实现了一个笔刷来捕获canvas元素的mousedownmousemovemouseup事件。所有这些都适合在画布上绘制。但是,我不认为我喜欢您的鼠标离开画布中线时如何无法继续绘图。它只是切断它。对这个人来说,这是非常宽容的,而且在我看来也不是很友好。

如果打开Microsoft Paint并使用画笔或椭圆形或其他东西开始绘制,只要在画布中开始,就可以将鼠标拖动到屏幕上的任意位置,然后在任何地方重新进入画布。例如,由于可以将椭圆工具拖到屏幕外,因此还可以轻松地在角上绘制四分之一圆。我希望这是有道理的。

无论如何,我想知道是否有一种方法可以用HTML5画布来实现,或者我将如何实现这种东西。用户将永远不必实际看到那里绘制的任何内容。它主要只是可用性的功能。

编辑:许多此类解决方案的问题是如何处理坐标。目前,我的画布位于屏幕中间,画布的左上方为(0, 0),右下方为(500, 500)。还必须考虑坐标的翻译工作。

Edit2:我发现您显然可以画出画布边界。例如,您可以提供负的宽度,高度和坐标,并且canvas元素可以很好地处理它。因此,基本上,该解决方案可能会涉及仅捕获文档的mousemovemouseup并仅转换xy从画布的左上角开始。

javascript jquery html5 canvas bounds
3个回答
1
投票

这里是一个非常粗糙的初稿,说明了如何在窗口而不是画布上侦听鼠标事件以能够连续绘制:

var logger = document.getElementById("logger"),
  mState = document.getElementById("mState"),
  mX = document.getElementById("mX"),
  mY = document.getElementById("mY"),
  cX = document.getElementById("cX"),
  cY = document.getElementById("cY"),
  c = document.getElementById("canvas"),
  ctx = c.getContext("2d");

var mouse = {
  x: 0,
  y: 0,
  state: ""
};

function printCanvasLocation() {
  var b = c.getBoundingClientRect();
  cX.innerHTML = b.top;
  cY.innerHTML = b.left;
}

function setState(mouseE, state) {
  mouse.x = mouseE.clientX;
  mouse.y = mouseE.clientY;

  mX.innerHTML = mouseE.clientX;
  mY.innerHTML = mouseE.clientY;
  if (state) {
    mState.innerHTML = state;
    mouse.state = state;
  }
}

window.addEventListener("mousedown", function(mouseE) {
  setState(mouseE, "down");
});

window.addEventListener("mouseup", function(mouseE) {
  setState(mouseE, "up");
});

window.addEventListener("mousemove", function(mouseE) {
  var offset = c.getBoundingClientRect();

  var fix = {
    x1: (mouse.x - offset.left),
    y1: (mouse.y - offset.top),
    x2: (mouseE.clientX - offset.left),
    y2: (mouseE.clientY - offset.top)
  };

  if (mouse.state === "down") {
    ctx.moveTo(fix.x1, fix.y1);
    ctx.lineTo(fix.x2, fix.y2);
    ctx.strokeStyle = "#000";
    ctx.stroke();
  }
  setState(mouseE);
});

window.addEventListener("resize", function() {
  printCanvasLocation();
});

printCanvasLocation();
            .center {

              text-align: center;

            }

            canvas {

              background-color: lightblue;

            }
<main>
  <div class="center">
    <canvas id="canvas" width="128" height="128">If you can see me, you should update your browser</canvas>
  </div>
  <div id="logger" role="log">
    <span>State: </span><span id="mState">Unknown</span>
    <span>X: </span><span id="mX">Unknown</span>
    <span>Y: </span><span id="mY">Unknown</span>
    <span>Canvas X: </span><span id="cX">Unknown</span>
    <span>Canvas Y: </span><span id="cY">Unknown</span>
  </div>
</main>

2
投票

这是重新进入画布时可以保持绘图的一种方法:

  • 创建一个全局变量,并在鼠标按下时将其设置为true
  • [为mouseup添加一个全局事件,这样您就可以了解是否有人在外面进行此操作画布,如果是这样,则将全局变量设置为false,当然,画布元素的mouseup也需要设置相同的变量
  • 在mousemove上,在绘制前检查全局变量是否为真

[在画布的外部绘制,就像角落中的四分之一圈一样,我将所有事件作为全局处理程序移到文档级别,并在单击时捕获画布元素,并将其客户坐标传递给文档坐标。


0
投票

一种解决方案是从字面上使画布成为窗口的大小,并以此缩放它的大小。画布几乎可以是透明的。

我敢肯定,还有一种方法可以使鼠标发生事件,如果需要的话,可以先通过画布,然后再传递到后面的元素。 (请参阅:“冒泡和捕获js事件”。)

但是您将拥有绝对的控制权,并能够在任何地方绘制任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.