我想做一个小绘画应用程序使用画布。所以我需要找到鼠标在画布上的位置。
当前回答
在纯javascript中没有答案,当reference元素嵌套在其他可以具有绝对定位的元素中时,返回相对坐标。下面是针对这种情况的解决方案:
function getRelativeCoordinates (event, referenceElement) {
const position = {
x: event.pageX,
y: event.pageY
};
const offset = {
left: referenceElement.offsetLeft,
top: referenceElement.offsetTop
};
let reference = referenceElement.offsetParent;
while(reference){
offset.left += reference.offsetLeft;
offset.top += reference.offsetTop;
reference = reference.offsetParent;
}
return {
x: position.x - offset.left,
y: position.y - offset.top,
};
}
其他回答
摘自本教程,感谢上面的评论做了更正:
function getMousePos( canvas, evt ) {
var rect = canvas.getBoundingClientRect();
return {
x: Math.floor( ( evt.clientX - rect.left ) / ( rect.right - rect.left ) * canvas.width ),
y: Math.floor( ( evt.clientY - rect.top ) / ( rect.bottom - rect.top ) * canvas.height )
};
}
在画布上使用如下:
var canvas = document.getElementById( 'myCanvas' );
canvas.addEventListener( 'mousemove', function( evt ) {
var mousePos = getMousePos( canvas, evt );
} );
对于使用JQuery的人:
有时,当您嵌套元素时,其中一个元素附加了事件,可能会让您难以理解浏览器将什么视为父元素。在这里,您可以指定哪个父节点。
取鼠标位置,然后从父元素的偏移位置中减去它。
var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;
如果你想在滚动窗格中获取页面上的鼠标位置:
var x = (evt.pageX - $('#element').offset().left) + self.frame.scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + self.frame.scrollTop();
或相对于页面的位置:
var x = (evt.pageX - $('#element').offset().left) + $(window).scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
注意以下性能优化:
var offset = $('#element').offset();
// Then refer to
var x = evt.pageX - offset.left;
通过这种方式,JQuery不必为每一行查找#element。
更新
在@anytimecoder的回答中有一个更新的、仅支持javascript的版本——另请参阅浏览器对getBoundingClientRect()的支持。
我尝试了所有这些解决方案,由于我的特殊设置与矩阵转换容器(panzoom库)没有工作。这将返回正确的值,即使缩放和窗格:
mouseevent(e) {
const x = e.offsetX,
y = e.offsetY
}
但前提是没有子元素。这可以通过使用CSS使它们对事件“不可见”来规避:
.child {
pointer-events: none;
}
你必须知道你的页面的结构,因为如果你的canvas是一个div的子div又是另一个div的子…然后,故事变得更加复杂。下面是我在2层div中创建一个canvas的代码:
canvas.addEventListener("click", function(event) {
var x = event.pageX - (this.offsetLeft + this.parentElement.offsetLeft);
var y = event.pageY - (this.offsetTop + this.parentElement.offsetTop);
console.log("relative x=" + x, "relative y" + y);
});
我意识到我有点晚了,但这与纯javascript工作,它甚至给你在元素内的指针的坐标,如果元素大于视口和用户已经滚动。
var element_offset_x ; // The distance from the left side of the element to the left of the content area
....// some code here (function declaration or element lookup )
element_offset_x = element.getBoundingClientRect().left - document.getElementsByTagName("html")[0].getBoundingClientRect().left ;
....// code here
function mouseMoveEvent(event)
{
var pointer_location = (event.clientX + window.pageXOffset) - element_offset_x ;
}
它是如何工作的。
我们要做的第一件事是获取HTML元素(内容区域)相对于当前视口的位置。如果页面有滚动条并且正在滚动,则getBoundingClientRect()返回的数字。HTML标记的左边将是负的。然后,我们使用这个数字来计算元素与内容区域左侧之间的距离。使用element_offset_x = element.getBoundingClientRect().left......;
知道元素到内容区域的距离。事件。clientX给出了指针到视口的距离。重要的是要理解视口和内容区域是两个不同的实体,如果页面被滚动,视口可以移动。因此,即使页面被滚动,clientX也将返回相同的数字。
为了弥补这一点,我们需要将指针的x位置(相对于视口)添加到视口的x位置(相对于内容区域)。视窗的X位置是通过window.pageXOffset找到的。