向canvas元素添加一个单击事件处理程序,返回单击的x和y坐标(相对于canvas元素),最简单的方法是什么?
不需要传统浏览器兼容性,Safari、Opera和Firefox就可以了。
向canvas元素添加一个单击事件处理程序,返回单击的x和y坐标(相对于canvas元素),最简单的方法是什么?
不需要传统浏览器兼容性,Safari、Opera和Firefox就可以了。
当前回答
这里是一个简化的解决方案(这并不适用于边框/滚动):
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),
};
}
其他回答
下面是对Ryan Artecona关于画布宽度可变(%)的答案的一个小修改:
HTMLCanvasElement.prototype.relMouseCoords = function (event) {
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var currentElement = this;
do {
totalOffsetX += currentElement.offsetLeft;
totalOffsetY += currentElement.offsetTop;
}
while (currentElement = currentElement.offsetParent)
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
// Fix for variable canvas width
canvasX = Math.round( canvasX * (this.width / this.offsetWidth) );
canvasY = Math.round( canvasY * (this.height / this.offsetHeight) );
return {x:canvasX, y:canvasY}
}
我做了一个完整的演示,可以在每个浏览器中使用这个问题的解决方案的完整源代码:在Javascript中单击Canvas的鼠标坐标。要尝试演示,复制代码并将其粘贴到文本编辑器中。然后将其保存为example.html,最后用浏览器打开该文件。
在Prototype中,使用cumulativeOffset()执行上面Ryan Artecona提到的递归求和。
http://www.prototypejs.org/api/element/cumulativeoffset
根据最新的Quirksmode,所有主流浏览器都支持clientX和clientY方法。 所以,它开始了-在滚动条页面上的滚动div中工作的良好工作代码:
function getCursorPosition(canvas, event) {
var x, y;
canoffset = $(canvas).offset();
x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - Math.floor(canoffset.left);
y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - Math.floor(canoffset.top) + 1;
return [x,y];
}
这也需要jQuery $(canvas).offset()。
以下是上述Ryan Artecona解决方案的一些修改。
function myGetPxStyle(e,p)
{
var r=window.getComputedStyle?window.getComputedStyle(e,null)[p]:"";
return parseFloat(r);
}
function myGetClick=function(ev)
{
// {x:ev.layerX,y:ev.layerY} doesn't work when zooming with mac chrome 27
// {x:ev.clientX,y:ev.clientY} not supported by mac firefox 21
// document.body.scrollLeft and document.body.scrollTop seem required when scrolling on iPad
// html is not an offsetParent of body but can have non null offsetX or offsetY (case of wordpress 3.5.1 admin pages for instance)
// html.offsetX and html.offsetY don't work with mac firefox 21
var offsetX=0,offsetY=0,e=this,x,y;
var htmls=document.getElementsByTagName("html"),html=(htmls?htmls[0]:0);
do
{
offsetX+=e.offsetLeft-e.scrollLeft;
offsetY+=e.offsetTop-e.scrollTop;
} while (e=e.offsetParent);
if (html)
{
offsetX+=myGetPxStyle(html,"marginLeft");
offsetY+=myGetPxStyle(html,"marginTop");
}
x=ev.pageX-offsetX-document.body.scrollLeft;
y=ev.pageY-offsetY-document.body.scrollTop;
return {x:x,y:y};
}