Javascript 如何在HTML画布元素外部绘制?

Javascript 如何在HTML画布元素外部绘制?,javascript,jquery,html,canvas,bounds,Javascript,Jquery,Html,Canvas,Bounds,我有一个HTML画布元素,并实现了一个画笔,它捕获画布元素的mousedown、mousemove和mouseup事件。这一切都适用于在画布上绘制。然而,我不认为我喜欢如果鼠标在笔划中间离开画布,你就不能继续画画。它只是把它切断了。在我看来,这对这个人来说是非常不宽容的,也不是非常友好的 如果打开Microsoft Paint并使用画笔或椭圆或其他工具开始绘制,只要在画布中开始,就可以将鼠标拖动到屏幕上的任何位置,然后在任何位置重新进入画布。例如,它还可以很容易地在拐角处绘制四分之一圆,因为您可

我有一个HTML画布元素,并实现了一个画笔,它捕获画布元素的
mousedown
mousemove
mouseup
事件。这一切都适用于在画布上绘制。然而,我不认为我喜欢如果鼠标在笔划中间离开画布,你就不能继续画画。它只是把它切断了。在我看来,这对这个人来说是非常不宽容的,也不是非常友好的

如果打开Microsoft Paint并使用画笔或椭圆或其他工具开始绘制,只要在画布中开始,就可以将鼠标拖动到屏幕上的任何位置,然后在任何位置重新进入画布。例如,它还可以很容易地在拐角处绘制四分之一圆,因为您可以将椭圆工具拖离屏幕。我希望这是有道理的

无论如何,我想知道是否有一种方法可以用HTML5画布实现这一点,或者我将如何实现这类事情。用户将永远不会看到任何画在那里的东西;它主要是一个可用性的特性

编辑:许多解决方案的一个问题是如何处理坐标。目前我的画布在屏幕的中间,画布的左上角是<代码>(0, 0)< /代码>,右下角是<代码>(500, 500)< /代码>。还必须考虑坐标的平移工作


Edit2:我发现很明显你可以很好地画出画布边界。例如,您可以提供负宽度、负高度和负坐标,canvas元素可以很好地处理它。因此,基本上,解决方案可能只需要捕获文档的
mousemove
mouseup
,然后将
x
y
转换为画布左上角的起点。

在重新进入画布时,有一种方法可以继续绘制:

  • 创建一个全局变量,并在mousedown中将该变量设置为true
  • 为mouseup添加一个全局事件,以便您可以捕捉到是否有人在外部执行此操作 canvas,如果是这样,将全局变量设置为false,canvas元素的mouseup当然也需要设置相同的变量
  • 在mousemove上,在绘制之前检查全局变量是否为true

要在画布的“外部”绘制,就像在角落中绘制四分之一圆,我会将所有事件作为全局处理程序移动到文档级别,并在单击时捕获画布元素,并传递其客户机坐标,以使用文档坐标进行计算。

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

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(“画布”),
ctx=c.getContext(“2d”);
变量鼠标={
x:0,,
y:0,
国家:“”
};
函数printCanvasLocation(){
var b=c.getBoundingClientRect();
cX.innerHTML=b.top;
cY.innerHTML=b.left;
}
函数设置状态(鼠标,状态){
mouse.x=mouseE.clientX;
mouse.y=mouseE.clientY;
mX.innerHTML=mouseE.clientX;
mY.innerHTML=mouseE.clientY;
如果(州){
mState.innerHTML=状态;
mouse.state=状态;
}
}
window.addEventListener(“mousedown”,函数(mouseE){
设置状态(鼠标“向下”);
});
window.addEventListener(“mouseup”,函数(mouseE){
设置状态(鼠标“向上”);
});
window.addEventListener(“mousemove”),函数(mouseE){
var offset=c.getBoundingClientRect();
变量固定={
x1:(鼠标.x-偏移量.左),
y1:(鼠标.y-偏移量.top),
x2:(mouseE.clientX-偏移量.左),
y2:(mouseE.clientY-offset.top)
};
如果(mouse.state==“down”){
ctx.moveTo(fix.x1,fix.y1);
ctx.lineTo(fix.x2,fix.y2);
ctx.strokeStyle=“#000”;
ctx.stroke();
}
设置状态(鼠标);
});
addEventListener(“调整大小”,函数(){
printCanvasLocation();
});
printCanvasLocation()
.center{
文本对齐:居中;
}
帆布{
背景颜色:浅蓝色;
}

如果你能看到我,你应该更新你的浏览器
国家:未知
X:未知
Y:不知道
画布X:未知
Y:未知

一种解决方案是将画布按窗口的大小进行缩放。画布可以是透明的

我相信还有一种方法可以让鼠标事件和类似的事件先通过画布,然后再通过后面的元素,如果需要的话。(请参阅:“js事件冒泡和捕获”。)


但是,这样你就可以拥有绝对的控制权,可以在任何地方绘制任何东西。

你能在窗口本身上捕获鼠标事件,然后将其委托给画布吗?也许可以尝试发布一个你目前拥有的示例。如果我们不必首先重新创建我们自己的“破碎”示例,那么就更容易提供帮助。也许您还可以将画布元素设置为窗口的全宽和全高,并将画布中的绘图区域缩小一些?@AidasBendoraitis:这也是一个非常好的主意。让我很快试一试。@zero298:你能演示一下怎么做吗?你的
Canvas X
Canvas Y
是向后的,但在其他方面反应很好!“我想这样就行了。”“安德烈,我不明白你的意思。如果您的意思是使用CSS或其他方法旋转画布,我会假设您需要将相同的矩阵乘法应用于从鼠标事件获得的坐标。