如何获得在画布元素上单击鼠标的坐标?


276

将click事件处理程序添加到canvas元素(将返回click的x和y坐标)(相对于canvas元素)的最简单方法是什么?

不需要旧版浏览器兼容性,Safari,Opera和Firefox都可以。


这与从普通dom元素获取鼠标事件没有什么不同。quirksmode在这方面有很好的参考。
airportyh

4
您上面列出的代码仅在画布不在其他容器中时有效。通常,您需要使用类似jquery偏移量函数的方法[var testDiv = $('#testDiv'); var offset = testDiv.offset();]以跨浏览器的方式获取正确的偏移量。这是真正的痛苦。
亚伦·沃特斯

如果包含画布的页面滚动,则上面通过Update发布的代码将无法正常工作。
蒂莫西·金

我删除了旧的“答案”,该答案是该问题的更新。如前所述,它已经过时且不完整。
汤姆(Tom)

3
由于这里有大约50个答案,因此我建议滚动到这个家伙的答案:patriques-一个好而简单的5个班轮。
伊戈尔·L.

Answers:


77

编辑2018:这个答案很老了,它使用检查不再需要的旧浏览器,因为clientXclientY属性在所有当前浏览器中都有效。您可能想查看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;

对我来说工作得很好。


30
这种解决方案并不总是有效的-当画布不一定相对于整个页面放置时,Ryan Artecona的答案在更一般的情况下有效。
克里斯·约翰逊

3
如果性能很重要,则不适合使用此解决方案,因为每次单击/移动都完成Dom访问。并且getBoundingClientRect现在存在,并且更加优雅。
GameAlchemist 2014年

192

如果您喜欢简单性,但仍然想要跨浏览器功能,那么我发现此解决方案最适合我。这是@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)
})

如果页面向下滚动,我猜也应该考虑文档的滚动偏移量。
Peppe LG 2014年

8
@ PeppeL-G边界客户端矩形会为您计算。在发表评论之前,您可以轻松地在控制台中对其进行测试(这就是我所做的)。
托马什Zato -恢复莫妮卡

1
@TomášZato,哦,getBoundingClientRect返回相对于视口的位置吗?然后我的猜测是错误的。我从来没有对其进行过测试,因为这对我来说从来都不是问题,并且我想警告其他读者我所看到的潜在问题,但是感谢您的澄清。
Peppe LG 2014年

1
如果画布已缩放,则此方法不起作用。不确定是否是浏览器错误。
Jeroen

2
为像我这样的人添加用法:var canvas = document.getElementById('canvasID'); canvas.addEventListener("mousedown", function (e) { getCursorPosition(canvas, e);});
SnowOnion

179

更新(5/5/16):应该使用爱国者的答案,因为它既简单又可靠。


由于画布并非总是相对于整个页面设置样式,因此画布canvas.offsetLeft/Top并不总是返回您所需的内容。它将返回相对于其offsetParent元素偏移的像素数,该像素数可能类似于div包含position: relative应用了样式的画布的元素。为了解决这个问题,您需要遍历offsetParents 链,从canvas元素本身开始。这段代码对我来说非常有效,已经在Firefox和Safari中进行了测试,但是应该对所有人都有效。

function relMouseCoords(event){
    var totalOffsetX = 0;
    var totalOffsetY = 0;
    var canvasX = 0;
    var canvasY = 0;
    var currentElement = this;

    do{
        totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
        totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
    }
    while(currentElement = currentElement.offsetParent)

    canvasX = event.pageX - totalOffsetX;
    canvasY = event.pageY - totalOffsetY;

    return {x:canvasX, y:canvasY}
}
HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;

最后一行使获取鼠标相对于画布元素的坐标变得很方便。获得有用的坐标所需要的是

coords = canvas.relMouseCoords(event);
canvasX = coords.x;
canvasY = coords.y;

8
不,它使用的是内置的JavaScript原型对象--- developer.mozilla.org/en/...
GARG

14
我的Chrome具有event.offsetXevent.offsetY属性,因此我通过添加修改了您的解决方案if (event.offsetX !== undefined && event.offsetY !== undefined) { return {x:event.offsetX, y:event.offsetY}; }。看起来很有效。
巴泽克

3
Baczek关于Chrome浏览器是正确的event.offsetXevent.offsetY它也可以在IE9中使用。对于Firefox(已通过v13测试),您可以使用event.layerXevent.layerY
mafafu 2012年

3
我还添加了以下内容: canvasX = event.pageX - totalOffsetX - document.body.scrollLeft; canvasY = event.pageY - totalOffsetY - document.body.scrollTop;
amirpc

4
答案的最终版本对我不起作用。在Firefox上,如果滚动整个屏幕,则会得到置换值作为输出。对我有用的是一个非常类似的解决方案,在stackoverflow.com/a/10816667/578749上给出了该解决方案,而不是event.pageX / Y,而是从event.clientX / Y中减去了计算出的偏移量。有人可以审查并解释吗?
lvella

33

现代浏览器现在可以为您解决这个问题。Chrome,IE9和Firefox这样支持offsetX / Y,并通过点击处理程序传递事件。

function getRelativeCoords(event) {
    return { x: event.offsetX, y: event.offsetY };
}

大多数现代浏览器还支持layerX / Y,但是Chrome和IE使用layerX / Y来表示页面上的点击的绝对偏移量,包括边距,填充等。在Firefox中,layerX / Y和offsetX / Y是等效的,但是offset却没有以前不存在。因此,为了与稍旧的浏览器兼容,可以使用:

function getRelativeCoords(event) {
    return { x: event.offsetX || event.layerX, y: event.offsetY || event.layerY };
}

1
有趣的是,如何在Chrome和Firefox上同时定义layerX,layerY,但是在Chrome上它是不准确的(或其他含义)。
朱利安·曼

@JulianMann感谢您的信息。我已根据更多最新支持更新了此答案。看起来您现在几乎可以普遍使用offsetX / Y了。
mafafu

18

根据新鲜怪异模式clientXclientY方法,在所有主要的浏览器都支持。因此,它来了-良好的工作代码可在带有滚动条的页面上的滚动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 for $(canvas).offset()


相当于@ N4ppeL答案。
帕维尔Szczur


11

这是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}
}

7

进行坐标转换时要小心;click事件中返回了多个非跨浏览器值。如果滚动浏览器窗口(在Firefox 3.5和Chrome 3.0中验证),仅使用clientX和clientY是不够的。

这个怪癖模式文章提供了一个更正确的功能,可以使用pageX或pageY或将clientX与document.body.scrollLeft结合使用,以及将clientY与document.body.scrollTop结合使用,以计算相对于文档原点的单击坐标。

更新:此外,offsetLeft和offsetTop是相对于元素的填充大小,而不是内部大小。应用padding:样式的画布不会将其内容区域的左上角报告为offsetLeft。有多种解决方案可以解决此问题。最简单的方法可能是清除画布本身上的所有边框,填充等样式,然后将它们应用于包含画布的盒子。


7

我不确定所有遍历父元素并做各种奇怪事情的答案的意义何在。

HTMLElement.getBoundingClientRect方法旨在处理任何元素的实际屏幕位置。这包括滚动,因此scrollTop不需要类似的东西:

(来自MDN)在计算边界矩形时,应考虑到视口区域(或任何其他可滚动元素)已经完成的滚动量

正常影像

非常简单的方法已经张贴在这里。只要涉及任何野生CSS规则,这都是正确的。

处理拉伸的画布/图像

当图像像素宽度与CSS宽度不匹配时,您需要对像素值应用一些比率:

/* Returns pixel coordinates according to the pixel that's under the mouse cursor**/
HTMLCanvasElement.prototype.relativeCoords = function(event) {
  var x,y;
  //This is the current screen rectangle of canvas
  var rect = this.getBoundingClientRect();
  var top = rect.top;
  var bottom = rect.bottom;
  var left = rect.left;
  var right = rect.right;
  //Recalculate mouse offsets to relative offsets
  x = event.clientX - left;
  y = event.clientY - top;
  //Also recalculate offsets of canvas is stretched
  var width = right - left;
  //I use this to reduce number of calculations for images that have normal size 
  if(this.width!=width) {
    var height = bottom - top;
    //changes coordinates by ratio
    x = x*(this.width/width);
    y = y*(this.height/height);
  } 
  //Return as an array
  return [x,y];
}

只要画布没有边框,它就可用于拉伸图像(jsFiddle)

处理CSS边框

如果帆布的边框很粗,那么事情就不会复杂了。您实际上需要从边界矩形中减去边框。这可以使用.getComputedStyle完成。这个答案描述了过程

然后,该函数会长大一些:

/* Returns pixel coordinates according to the pixel that's under the mouse cursor**/
HTMLCanvasElement.prototype.relativeCoords = function(event) {
  var x,y;
  //This is the current screen rectangle of canvas
  var rect = this.getBoundingClientRect();
  var top = rect.top;
  var bottom = rect.bottom;
  var left = rect.left;
  var right = rect.right;
  //Subtract border size
  // Get computed style
  var styling=getComputedStyle(this,null);
  // Turn the border widths in integers
  var topBorder=parseInt(styling.getPropertyValue('border-top-width'),10);
  var rightBorder=parseInt(styling.getPropertyValue('border-right-width'),10);
  var bottomBorder=parseInt(styling.getPropertyValue('border-bottom-width'),10);
  var leftBorder=parseInt(styling.getPropertyValue('border-left-width'),10);
  //Subtract border from rectangle
  left+=leftBorder;
  right-=rightBorder;
  top+=topBorder;
  bottom-=bottomBorder;
  //Proceed as usual
  ...
}

我想不出任何会混淆此最终功能的东西。在JsFiddle见。

笔记

如果你不喜欢修改本地prototypeS,只是改变了功能,并调用它(canvas, event)(并更换thiscanvas)。


6

这是一个非常不错的教程-

http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/

 <canvas id="myCanvas" width="578" height="200"></canvas>
<script>
  function writeMessage(canvas, message) {
    var context = canvas.getContext('2d');
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.font = '18pt Calibri';
    context.fillStyle = 'black';
    context.fillText(message, 10, 25);
  }
  function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
  }
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');

  canvas.addEventListener('mousemove', function(evt) {
    var mousePos = getMousePos(canvas, evt);
    var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
    writeMessage(canvas, message);
  }, false);

希望这可以帮助!


Ryan Artecona的解决方案不适用于带缩放功能的平板电脑浏览器。然而,这确实做到了。
安迪·迈耶斯

不适用于具有CSS width/ height覆盖但仍然是最佳解决方案之一的图像。
托马什Zato -恢复莫妮卡

3

我在2016年使用jQuery,以获得相对于画布的点击坐标,我这样做:

$(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())
}

哇。“ jqEvent”如何定义?还是“画布”?还是在第二个示例中,“坐标”?您是否需要在第二个示例之前运行第一个示例?在那种情况下,你为什么不写“得到那些,你也会做”?所有这些都在onclick函数中吗?给一点背景,伴侣。考虑到最初的问题是在2008年提出的,我认为您需要在2008年可用的技术范围内进行回答。请使用当时可用版本(v1.2)中的有效jQuery来完善您的回答。;)
Ayelis '16

1
好,抱歉我的冒昧。我将删除该内容。我确实打算使用最新的框架来提供答案。而且我相信程序员无需解释jqEvent,canvas和coords是什么。
Sarsaparilla

看起来挺好的。感谢您的输入!对不起,我给你带来了辛苦!;)
Ayelis '16

3

因此,这既简单,又比看起来要复杂一些。

首先,这里通常会混淆一些问题

  1. 如何获取元素相对鼠标坐标

  2. 如何获取2D Canvas API或WebGL的画布像素鼠标坐标

所以,答案

如何获取元素相对鼠标坐标

元素是否是画布,获取元素相对鼠标坐标对于所有元素都是相同的。

对于“如何获取画布相对鼠标坐标”这个问题,有2个简单的答案

简单答案#1的使用offsetXoffsetY

canvas.addEventListner('mousemove', (e) => {
  const x = e.offsetX;
  const y = e.offsetY;
});

此答案适用于Chrome,Firefox和Safari。与所有其他事件值不同,offsetXoffsetY考虑了CSS转换。

与最大的问题offsetXoffsetY是为2019/05他们不触摸事件存在,因此无法与iOS Safari浏览器中使用。它们确实存在于Chrome和Firefox中存在的Pointer Events中,但Safari中不存在,尽管Safari显然正在使用它

另一个问题是事件必须在画布本身上。如果将它们放在其他元素或窗口上,则以后将无法选择画布作为参考。

简单答案2使用clientXclientYcanvas.getBoundingClientRect

如果你不关心CSS转换下一个简单的答案是调用canvas. getBoundingClientRect()和减去从左边clientXtopclientY

canvas.addEventListener('mousemove', (e) => {
  const rect = canvas.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
});

只要没有CSS转换,这将起作用。它还适用于触摸事件,因此也适用于Safari iOS

canvas.addEventListener('touchmove', (e) => {
  const rect = canvas. getBoundingClientRect();
  const x = e.touches[0].clientX - rect.left;
  const y = e.touches[0].clientY - rect.top;
});

如何获取2D Canvas API的画布像素鼠标坐标

为此,我们需要获取上面得到的值,并将画布显示的尺寸转换为画布本身的像素数

canvas.getBoundingClientRectclientXclientY

canvas.addEventListener('mousemove', (e) => {
  const rect = canvas.getBoundingClientRect();
  const elementRelativeX = e.clientX - rect.left;
  const elementRelativeY = e.clientY - rect.top;
  const canvasRelativeX = elementRelativeX * canvas.width / rect.width;
  const canvasRelativeY = elementRelativeY * canvas.height / rect.height;
});

offsetXoffsetY

canvas.addEventListener('mousemove', (e) => {
  const elementRelativeX = e.offsetX;
  const elementRelativeX = e.offsetY;
  const canvasRelativeX = elementRelativeX * canvas.width / canvas.clientWidth;
  const canvasRelativeY = elementRelativeX * canvas.height / canvas.clientHeight;
});

注意:在所有情况下,请勿在画布上添加填充或边框。这样做会使代码复杂化。而不是您希望边框或填充在其他元素中包围画布,并向外部元素添加填充和/或边框。

使用的工作示例event.offsetXevent.offsetY

用工作实例canvas.getBoundingClientRect,并event.clientXevent.clientY


2

我建议使用此链接-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>

有什么意义x = new Number()?下面的代码重新分配x,这意味着分配的编号立即被丢弃
gman


1

您可以这样做:

var canvas = yourCanvasElement;
var mouseX = (event.clientX - (canvas.offsetLeft - canvas.scrollLeft)) - 2;
var mouseY = (event.clientY - (canvas.offsetTop - canvas.scrollTop)) - 2;

这将为您提供鼠标指针的确切位置。


1

请参见http://jsbin.com/ApuJOSA/1/edit?html上的演示,输出。

  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 };
  }

0

这是上述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};
}

0

首先,正如其他人所说,您需要一个函数来获取canvas元素位置。这是一种比此页面上的其他方法(IMHO)更优雅的方法。您可以将其传递给任何元素,并获得其在文档中的位置:

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函数与事件处理代码。(应该如此。我们应该尝试将我们的功能保持在一项任务之内。)

的值offsetLeftoffsetTop相对于offsetParent,这可能是一些包装div节点(或其他任何东西,对于这个问题)。当没有元素包装时canvas它们是相对于的body,因此没有要减去的偏移量。这就是为什么在执行其他任何操作之前需要确定画布的位置的原因。

相似 e.pageXe.pageY给出光标相对于文档的位置。这就是为什么我们从这些值中减去画布的偏移量以获得真实位置的原因。

一种替代定位的元件是直接使用的值e.layerXe.layerY。由于以下两个原因,它比上面的方法更不可靠:

  1. 当事件不在已定位的元素内发生时,这些值也相对于整个文档
  2. 它们不属于任何标准

0

ThreeJS r77

var x = event.offsetX == undefined ? event.layerX : event.offsetX;
var y = event.offsetY == undefined ? event.layerY : event.offsetY;

mouse2D.x = ( x / renderer.domElement.width ) * 2 - 1;
mouse2D.y = - ( y / renderer.domElement.height ) * 2 + 1;

经过尝试许多解决方案。这对我有用。可能会帮助其他人,因此发布。从这里得到


0

这是一个简化的解决方案(不适用于边框/滚动):

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),
    };
}

0

我正在创建一个在pdf上具有画布的应用程序,其中涉及许多画布的调整大小,例如“放大和缩小pdf”,然后依次打开每个PDF的放大/缩小,我必须调整画布的大小以适应pdf的大小,我在stackOverflow中经历了很多答案,但没有找到最终解决问题的完美解决方案。

我正在使用rxjs和angular 6,但未找到最新版本的任何答案。

对于使用rxjs在画布上绘制的任何人来说,这都是有用的完整代码段。

  private captureEvents(canvasEl: HTMLCanvasElement) {

    this.drawingSubscription = fromEvent(canvasEl, 'mousedown')
      .pipe(
        switchMap((e: any) => {

          return fromEvent(canvasEl, 'mousemove')
            .pipe(
              takeUntil(fromEvent(canvasEl, 'mouseup').do((event: WheelEvent) => {
                const prevPos = {
                  x: null,
                  y: null
                };
              })),

              takeUntil(fromEvent(canvasEl, 'mouseleave')),
              pairwise()
            )
        })
      )
      .subscribe((res: [MouseEvent, MouseEvent]) => {
        const rect = this.cx.canvas.getBoundingClientRect();
        const prevPos = {
          x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
          y:  Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
        };
        const currentPos = {
          x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
          y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
        };

        this.coordinatesArray[this.file.current_slide - 1].push(prevPos);
        this.drawOnCanvas(prevPos, currentPos);
      });
  }

此处是固定的代码段,无论您如何放大/缩小画布,鼠标相对于画布大小的坐标。

const prevPos = {
  x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
  y:  Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
const currentPos = {
  x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
  y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};

-1

嘿,这是在dojo中,只是因为这就是我已经在一个项目中使用的代码。

如何将其转换回非dojo vanilla JavaScript应该是相当明显的。

  function onMouseClick(e) {
      var x = e.clientX;
      var y = e.clientY;
  }
  var canvas = dojo.byId(canvasId);
  dojo.connect(canvas,"click",onMouseClick);

希望能有所帮助。


6
clientX / clientY在不同浏览器上的行为不同。
tfwright
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.