我想做一个小绘画应用程序使用画布。所以我需要找到鼠标在画布上的位置。
当前回答
摘自本教程,感谢上面的评论做了更正:
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 );
} );
其他回答
摘自本教程,感谢上面的评论做了更正:
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 );
} );
基于@Spider的解决方案,我的非JQuery版本是这样的:
// Get the container element's bounding box
var sides = document.getElementById("container").getBoundingClientRect();
// Apply the mouse event listener
document.getElementById("canvas").onmousemove = (e) => {
// Here 'self' is simply the current window's context
var x = (e.clientX - sides.left) + self.pageXOffset;
var y = (e.clientY - sides.top) + self.pageYOffset;
}
这适用于滚动和缩放(在这种情况下,有时它返回浮动)。
对于那些为移动设备和/或笔记本电脑/触摸屏显示器开发常规网站或PWAs(渐进式Web应用程序)的人来说,你可能已经登陆这里了,因为你可能已经习惯了鼠标事件,对触摸事件的痛苦体验还不熟悉……耶!
只有3条规则:
在鼠标移动或触摸移动事件期间尽可能少做。 在鼠标按下或触摸启动事件期间尽可能多地进行操作。 取消传播并防止触摸事件的默认值,以防止鼠标事件也在混合设备上触发。
不用说,触摸事件更复杂,因为可以有多个触摸事件,它们比鼠标事件更灵活(复杂)。这里我只讲一个触碰。是的,我很懒,但这是最常见的触摸方式。
var posTop; var posLeft; function handleMouseDown(evt) { var e = evt || window.event; // Because Firefox, etc. posTop = e.target.offsetTop; posLeft = e.target.offsetLeft; e.target.style.background = "red"; // The statement above would be better handled by CSS // but it's just an example of a generic visible indicator. } function handleMouseMove(evt) { var e = evt || window.event; var x = e.offsetX; // Wonderfully var y = e.offsetY; // Simple! e.target.innerHTML = "Mouse: " + x + ", " + y; if (posTop) e.target.innerHTML += "<br>" + (x + posLeft) + ", " + (y + posTop); } function handleMouseOut(evt) { var e = evt || window.event; e.target.innerHTML = ""; } function handleMouseUp(evt) { var e = evt || window.event; e.target.style.background = "yellow"; } function handleTouchStart(evt) { var e = evt || window.event; var rect = e.target.getBoundingClientRect(); posTop = rect.top; posLeft = rect.left; e.target.style.background = "green"; e.preventDefault(); // Unnecessary if using Vue.js e.stopPropagation(); // Same deal here } function handleTouchMove(evt) { var e = evt || window.event; var pageX = e.touches[0].clientX; // Touches are page-relative var pageY = e.touches[0].clientY; // not target-relative var x = pageX - posLeft; var y = pageY - posTop; e.target.innerHTML = "Touch: " + x + ", " + y; e.target.innerHTML += "<br>" + pageX + ", " + pageY; e.preventDefault(); e.stopPropagation(); } function handleTouchEnd(evt) { var e = evt || window.event; e.target.style.background = "yellow"; // Yes, I'm being lazy and doing the same as mouseout here // but obviously you could do something different if needed. e.preventDefault(); e.stopPropagation(); } div { background: yellow; height: 100px; left: 50px; position: absolute; top: 80px; user-select: none; /* Disable text selection */ -ms-user-select: none; width: 100px; } <div onmousedown="handleMouseDown()" onmousemove="handleMouseMove()" onmouseout="handleMouseOut()" onmouseup="handleMouseUp()" ontouchstart="handleTouchStart()" ontouchmove="handleTouchMove()" ontouchend="handleTouchEnd()"> </div> Move over box for coordinates relative to top left of box.<br> Hold mouse down or touch to change color.<br> Drag to turn on coordinates relative to top left of page.
更喜欢使用Vue.js?我做!然后你的HTML看起来是这样的:
<div @mousedown="handleMouseDown"
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
@touchstart.stop.prevent="handleTouchStart"
@touchmove.stop.prevent="handleTouchMove"
@touchend.stop.prevent="handleTouchEnd">
在纯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,
};
}
你可以使用相对父类的getBoudingClientRect()。
document.addEventListener("mousemove", (e) => {
let xCoord = e.clientX - e.target.getBoundingClientRect().left + e.offsetX
let yCoord = e.clientY - e.target.getBoundingClientRect().top + e.offsetY
console.log("xCoord", xCoord, "yCoord", yCoord)
})