向canvas元素添加一个单击事件处理程序,返回单击的x和y坐标(相对于canvas元素),最简单的方法是什么?
不需要传统浏览器兼容性,Safari、Opera和Firefox就可以了。
向canvas元素添加一个单击事件处理程序,返回单击的x和y坐标(相对于canvas元素),最简单的方法是什么?
不需要传统浏览器兼容性,Safari、Opera和Firefox就可以了。
当前回答
如果你喜欢简单,但仍然需要跨浏览器功能,我发现这个解决方案最适合我。这是一个简化的@Aldekein的解决方案,但没有jQuery。
function getCursorPosition(canvas, event) {
const rect = canvas.getBoundingClientRect()
const x = event.clientX - rect.left
const y = event.clientY - rect.top
console.log("x: " + x + " y: " + y)
}
const canvas = document.querySelector('canvas')
canvas.addEventListener('mousedown', function(e) {
getCursorPosition(canvas, e)
})
其他回答
参见http://jsbin.com/ApuJOSA/1/edit?html,output上的演示。
function mousePositionOnCanvas(e) {
var el=e.target, c=el;
var scaleX = c.width/c.offsetWidth || 1;
var scaleY = c.height/c.offsetHeight || 1;
if (!isNaN(e.offsetX))
return { x:e.offsetX*scaleX, y:e.offsetY*scaleY };
var x=e.pageX, y=e.pageY;
do {
x -= el.offsetLeft;
y -= el.offsetTop;
el = el.offsetParent;
} while (el);
return { x: x*scaleX, y: y*scaleY };
}
在Prototype中,使用cumulativeOffset()执行上面Ryan Artecona提到的递归求和。
http://www.prototypejs.org/api/element/cumulativeoffset
这里是一个简化的解决方案(这并不适用于边框/滚动):
function click(event) {
const bound = event.target.getBoundingClientRect();
const xMult = bound.width / can.width;
const yMult = bound.height / can.height;
return {
x: Math.floor(event.offsetX / xMult),
y: Math.floor(event.offsetY / yMult),
};
}
首先,正如其他人所说,您需要一个函数来获取canvas元素的位置。这里有一个方法,它比本页上的其他一些方法更优雅。你可以将任何元素传递给它,并获得它在文档中的位置:
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
现在计算游标相对于它的当前位置:
$('#canvas').mousemove(function(e) {
var pos = findPos(this);
var x = e.pageX - pos.x;
var y = e.pageY - pos.y;
var coordinateDisplay = "x=" + x + ", y=" + y;
writeCoordinateDisplay(coordinateDisplay);
});
注意,我将泛型findPos函数与事件处理代码分开。(本来就应该如此。我们应该尽量让每个函数只执行一个任务。)
offsetLeft和offsetTop的值相对于offsetParent,它可以是某个包装器div节点(或者其他任何东西)。当没有元素包裹画布时,它们是相对于主体的,因此没有要减去的偏移量。这就是为什么我们需要在做其他事情之前确定画布的位置。
类似地,e.pageX和e.pageY给出了光标相对于文档的位置。这就是为什么我们从这些值中减去画布的偏移量来达到真实位置。
定位元素的另一种选择是直接使用e.layerX和e.layerY的值。这种方法不如上面的方法可靠,有两个原因:
当事件不在定位的元素中发生时,这些值也相对于整个文档 它们不是任何标准的一部分
嘿,这是在dojo,只是因为它是我已经在一个项目的代码。
如何将其转换回非dojo的普通JavaScript应该是相当明显的。
function onMouseClick(e) {
var x = e.clientX;
var y = e.clientY;
}
var canvas = dojo.byId(canvasId);
dojo.connect(canvas,"click",onMouseClick);
希望这能有所帮助。