我想做一个小绘画应用程序使用画布。所以我需要找到鼠标在画布上的位置。
当前回答
基于@Patrick Boos的解决方案,但修复了中间滚动条的潜在问题。
export function getRelativeCoordinates(event: MouseEvent, referenceElement: HTMLElement) {
const position = {
x: event.pageX,
y: event.pageY,
};
const offset = {
left: referenceElement.offsetLeft,
top: referenceElement.offsetTop,
};
let reference = referenceElement.offsetParent as HTMLElement;
while (reference) {
offset.left += reference.offsetLeft;
offset.top += reference.offsetTop;
reference = reference.offsetParent as HTMLElement;
}
const scrolls = {
left: 0,
top: 0,
};
reference = event.target as HTMLElement;
while (reference) {
scrolls.left += reference.scrollLeft;
scrolls.top += reference.scrollTop;
reference = reference.parentElement as HTMLElement;
}
return {
x: position.x + scrolls.left - offset.left,
y: position.y + scrolls.top - offset.top,
};
}
其他回答
在纯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,
};
}
canvas.onmousedown = function(e) {
pos_left = e.pageX - e.currentTarget.offsetLeft;
pos_top = e.pageY - e.currentTarget.offsetTop;
console.log(pos_left, pos_top)
}
HTMLElement.offsetLeft
HTMLElement。offsetLeft read-only属性返回当前元素的左上角在HTMLElement中向左偏移的像素数。offsetParent节点。
对于块级元素,offsetTop, offsetLeft, offsetWidth和offsetHeight描述了一个元素相对于offsetParent的边界框。
However, for inline-level elements (such as span) that can wrap from one line to the next, offsetTop and offsetLeft describe the positions of the first border box (use Element.getClientRects() to get its width and height), while offsetWidth and offsetHeight describe the dimensions of the bounding border box (use Element.getBoundingClientRect() to get its position). Therefore, a box with the left, top, width and height of offsetLeft, offsetTop, offsetWidth and offsetHeight will not be a bounding box for a span with wrapped text.
HTMLElement.offsetTop
HTMLElement。offsetTop只读属性返回当前元素相对于offsetParent节点顶部的距离。
MouseEvent.pageX
pageX只读属性返回事件相对于整个文档的X(水平)坐标(像素)。此属性考虑页面的任何水平滚动。
MouseEvent.pageY
鼠标事件。pageY只读属性返回事件相对于整个文档的Y(垂直)像素坐标。此属性考虑页面的任何垂直滚动。
如需进一步解释,请参阅Mozilla开发者网络:
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageX https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageY https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop
我意识到我有点晚了,但这与纯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找到的。
Mark van Wyk的回答让我找到了正确的方向,但并没有完全解决我的问题。我仍然在另一个元素中包含的元素中绘画。
以下解决了它为我:
x = e.pageX - this.offsetLeft - $(elem).offset().left;
y = e.pageY - this.offsetTop - $(elem).offset().top;
换句话说,我简单地堆叠了所有嵌套元素的偏移量
我遇到了这个问题,但为了使它适用于我的情况(在dom元素上使用拖拽(在我的情况下不是画布)),我发现你只需要在拖拽鼠标事件上使用offsetX和offsetY。
onDragOver(event){
var x = event.offsetX;
var y = event.offsetY;
}