javascript – 画布中的真实鼠标位置
作者:互联网
参见英文答案 > How do I get the coordinates of a mouse click on a canvas element? 22个
我试图用鼠标画在HTML5画布上,但它似乎运行良好的唯一方法是如果画布位于0,0(左上角),如果我改变画布位置,由于某种原因它不会像它应该画的那样.这是我的代码.
function createImageOnCanvas(imageId){
document.getElementById("imgCanvas").style.display = "block";
document.getElementById("images").style.overflowY= "hidden";
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
var img = new Image(300,300);
img.src = document.getElementById(imageId).src;
context.drawImage(img, (0),(0));
}
function draw(e){
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
posx = e.clientX;
posy = e.clientY;
context.fillStyle = "#000000";
context.fillRect (posx, posy, 4, 4);
}
HTML部分
<body>
<div id="images">
</div>
<canvas onm ousemove="draw(event)" style="margin:0;padding:0;" id="imgCanvas"
class="canvasView" width="250" height="250"></canvas>
我已经读过有一种方法可以在JavaScript中创建一个简单的函数来获得正确的位置,但我不知道如何做到这一点.
解决方法:
简单的1:1场景
对于canvas元素与位图大小相比为1:1的情况,您可以使用以下代码段获取鼠标位置:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
只需使用事件和画布作为参数从事件中调用它.它返回一个带有x和y的对象,用于鼠标位置.
由于您获得的鼠标位置是相对于客户端窗口,您必须减去canvas元素的位置以将其相对于元素本身进行转换.
代码中的集成示例:
//put this outside the event loop..
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
function draw(evt) {
var pos = getMousePos(canvas, evt);
context.fillStyle = "#000000";
context.fillRect (pos.x, pos.y, 4, 4);
}
注意:如果直接应用于canvas元素,则border和padding将影响位置,因此需要通过getComputedStyle()来考虑这些位置,或者将这些样式应用于父div.
当元素和位图具有不同的大小时
当存在元素与位图本身不同的情况时,例如,使用CSS缩放元素或者存在像素长宽比等,您将不得不解决此问题.
例:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect(), // abs. size of element
scaleX = canvas.width / rect.width, // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
return {
x: (evt.clientX - rect.left) * scaleX, // scale mouse coordinates after they have
y: (evt.clientY - rect.top) * scaleY // been adjusted to be relative to element
}
}
将变换应用于上下文(比例,旋转等)
然后有一个更复杂的情况,你已经将变换应用于上下文,如旋转,倾斜/剪切,缩放,平移等.为了解决这个问题,你可以计算当前矩阵的逆矩阵.
较新的浏览器允许您通过currentTransform属性读取当前矩阵,Firefox(当前alpha)甚至通过mozCurrentTransformInverted提供反转矩阵.但是,通过mozCurrentTransform,Firefox将返回一个数组而不是DOMMatrix.当通过实验标志启用时,Chrome都不会返回DOMMatrix而是返回SVGMatrix.
但在大多数情况下,您必须实现自己的自定义矩阵解决方案(例如我自己的解决方案here – free / MIT项目),直到获得完全支持.
当你最终获得矩阵时,不管你获取矩阵的路径如何,你都需要将其反转并将其应用到鼠标坐标.然后将坐标传递给画布,画布将使用其矩阵将其转换回目前的任何位置.
这样,该点将相对于鼠标处于正确的位置.此外,您还需要将坐标(在应用逆矩阵之前)调整为相对于元素.
仅显示矩阵步骤的示例
function draw(evt) {
var pos = getMousePos(canvas, evt); // get adjusted coordinates as above
var imatrix = matrix.inverse(); // get inverted matrix somehow
pos = imatrix.applyToPoint(pos.x, pos.y); // apply to adjusted coordinate
context.fillStyle = "#000000";
context.fillRect(pos.x-1, pos.y-1, 2, 2);
}
Example using the solution linked above(在更广泛支持时替换为本机浏览器解决方案).
实现时使用currentTransform的示例如下:
var pos = getMousePos(canvas, e); // get adjusted coordinates as above
var matrix = ctx.currentTransform; // W3C (future)
var imatrix = matrix.invertSelf(); // invert
// apply to point:
var x = pos.x * imatrix.a + pos.y * imatrix.c + imatrix.e;
var y = pos.x * imatrix.b + pos.y * imatrix.d + imatrix.f;
更新我制作了一个免费解决方案(MIT),将所有这些步骤嵌入到一个易于使用的对象中,该对象可以在here找到,并且还可以处理其他一些最容易忽视的细节.
标签:mouse-position,javascript,canvas,html5-canvas 来源: https://codeday.me/bug/20190911/1804082.html