向canvas元素添加一个单击事件处理程序,返回单击的x和y坐标(相对于canvas元素),最简单的方法是什么?
不需要传统浏览器兼容性,Safari、Opera和Firefox就可以了。
向canvas元素添加一个单击事件处理程序,返回单击的x和y坐标(相对于canvas元素),最简单的方法是什么?
不需要传统浏览器兼容性,Safari、Opera和Firefox就可以了。
当前回答
以下是上述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};
}
其他回答
使用jQuery在2016年,以获得相对于画布的点击坐标,我做:
$(canvas).click(function(jqEvent) {
var coords = {
x: jqEvent.pageX - $(canvas).offset().left,
y: jqEvent.pageY - $(canvas).offset().top
};
});
这可以工作,因为canvas offset()和jqEvent。pageX/Y相对于文档,而不管滚动位置。
注意,如果你的画布是按比例缩放的,那么这些坐标与画布逻辑坐标是不一样的。要得到这些,你还需要做:
var logicalCoords = {
x: coords.x * (canvas.width / $(canvas).width()),
y: coords.y * (canvas.height / $(canvas).height())
}
我推荐这个链接 http://miloq.blogspot.in/2011/05/coordinates-mouse-click-canvas.html
<style type="text/css">
#canvas{background-color: #000;}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", init, false);
function init()
{
var canvas = document.getElementById("canvas");
canvas.addEventListener("mousedown", getPosition, false);
}
function getPosition(event)
{
var x = new Number();
var y = new Number();
var canvas = document.getElementById("canvas");
if (event.x != undefined && event.y != undefined)
{
x = event.x;
y = event.y;
}
else // Firefox method to get the position
{
x = event.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
alert("x: " + x + " y: " + y);
}
</script>
在进行坐标转换时要小心;在单击事件中返回多个非跨浏览器的值。如果浏览器窗口是滚动的(在Firefox 3.5和Chrome 3.0中验证),仅使用clientX和clienti是不够的。
这篇怪异模式文章提供了一个更正确的函数,可以使用pageX或pageY,或者使用clientX与document.body. scrollleft和clienti与document.body. scrolltop的组合来计算相对于文档原点的单击坐标。
更新:另外,offsetLeft和offsetTop是相对于元素的填充大小,而不是内部大小。应用了padding: style的画布不会将其内容区域的左上角报告为offsetLeft。这个问题有多种解决方案;最简单的方法可能是清除画布本身的所有边框、填充等样式,而是将它们应用到包含画布的框中。
我做了一个完整的演示,可以在每个浏览器中使用这个问题的解决方案的完整源代码:在Javascript中单击Canvas的鼠标坐标。要尝试演示,复制代码并将其粘贴到文本编辑器中。然后将其保存为example.html,最后用浏览器打开该文件。
Edit 2018:这个答案很老了,它使用检查不再需要的旧浏览器,因为clientX和clienti属性在所有当前的浏览器中都有效。您可能想要查看Patriques Answer,以获得一个更简单、更近期的解决方案。
最初的回答: 正如我当时发现的一篇文章所描述的那样,但现在已经不存在了:
var x;
var y;
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
x -= gCanvasElement.offsetLeft;
y -= gCanvasElement.offsetTop;
对我来说效果很好。