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

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

不需要传统浏览器兼容性,Safari、Opera和Firefox就可以了。

346217 次浏览

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

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

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

希望这能有所帮助。

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

这个怪癖模式 article提供了一个更正确的函数,可以使用pageX或pageY,或者使用clientX与document.body. scrollleft和clienti与document.body. scrolltop的组合来计算相对于文档原点的点击坐标。

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

2018年编辑:这个答案相当老,它使用检查旧浏览器不再需要,因为clientXclientY属性在所有当前的浏览器中都可以工作。你可能想要检查Patriques回答,以获得一个更简单、更近期的解决方案。

< p > 最初的回答: < br > 正如我在当时发现的一篇文章中所描述的那样,但现在已经不存在了:

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;

对我来说效果很好。

根据fresh Quirksmode,所有主流浏览器都支持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];
}

这也需要$(canvas).offset()jQuery

我做了一个完整的演示,工作在每个浏览器与此问题的解决方案的完整源代码:Javascript中鼠标在Canvas上点击的坐标。要尝试演示,复制代码并将其粘贴到文本编辑器中。然后将其保存为example.html,最后用浏览器打开该文件。

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


由于画布的样式并不总是相对于整个页面,canvas.offsetLeft/Top并不总是返回你需要的东西。它将返回相对于其offsetParent元素偏移的像素数,该元素可以是类似div元素的东西,其中包含应用了position: relative样式的画布。为了说明这一点,你需要遍历__abc3的链,从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;

最后一行可以方便地获取相对于canvas元素的鼠标坐标。要得到有用的坐标只需要

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

在Prototype中,使用cumulativeOffset()执行上面Ryan Artecona提到的递归求和。

http://www.prototypejs.org/api/element/cumulativeoffset

下面是对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}
}

现代浏览器现在可以帮你处理这个。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 };
}

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

这是一个非常好的教程-

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

希望这能有所帮助!

我推荐这个链接 http://miloq.blogspot.in/2011/05/coordinates-mouse-click-canvas.html < / p >

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

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

你可以这样做:

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

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

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

首先,正如其他人所说,你需要一个函数来获得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函数与事件处理代码分离。(这是应该的。我们应该尽量让每个函数只执行一个任务。)

offsetLeftoffsetTop的值是相对于offsetParent的,它可以是某个包装器div节点(或者其他任何东西)。当没有元素包装canvas时,它们是相对于body的,因此没有要减去的偏移量。这就是为什么我们需要在做其他事情之前确定画布的位置。

类似地,e.pageXe.pageY给出了光标相对于文档的位置。这就是为什么我们从这些值中减去画布的偏移量来达到真实位置。

定位元素的替代方法是直接使用e.layerXe.layerY的值。这种方法不如上面的方法可靠,有两个原因:

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

我不确定所有这些遍历父元素和做各种奇怪的东西的答案的意义是什么。

HTMLElement.getBoundingClientRect方法被设计用来处理任何元素的实际屏幕位置。这包括滚动,所以像scrollTop这样的东西是不需要的:

< >强(从MDN) < / >强已完成的视口区域(或 任何其他可滚动的元素)在计算 边界矩形< / p >

正常的图片

非常简单的方法已经发布在这里。只要涉及到没有原始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 < / >强见。

笔记

如果你不喜欢修改本机__abc0,只需更改函数并用(canvas, event)调用它(并用canvas替换任意this)。

使用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相对于文档,而不管滚动位置。

注意,如果你的画布是缩放的,那么这些坐标与canvas 逻辑坐标是不一样的。要得到这些,你可以这样做:

var logicalCoords = {
x: coords.x * (canvas.width / $(canvas).width()),
y: coords.y * (canvas.height / $(canvas).height())
}

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;

在尝试了许多解决方案后。这对我很管用。可能会帮助其他人,因此发帖。从在这里得到的

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

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

所以这是一个简单但比看起来更复杂的话题。

首先,这里通常有一些合并的问题

  1. < p > 如何获得元素相对鼠标坐标

  2. < p > 如何获得画布像素鼠标坐标为2D画布API或WebGL

所以,答案

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

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

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

简单的答案#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中,但不包括Safari,尽管显然Safari正在努力解决这个问题

另一个问题是事件必须在画布本身上。如果你把它们放在其他元素或窗口上,你以后就不能选择画布作为你的参考点了。

简单答案#2使用clientXclientYcanvas.getBoundingClientRect

如果你不关心CSS转换,下一个最简单的答案是调用canvas. getBoundingClientRect()并从clientX中减去左边,从clientY中减去top

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画布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 elementRelativeY = e.offsetY;
const canvasRelativeX = elementRelativeX * canvas.width / canvas.clientWidth;
const canvasRelativeY = elementRelativeY * canvas.height / canvas.clientHeight;
});

注意:在任何情况下都不要给画布添加填充或边框。这样做将极大地复杂化代码。而不是你想要一个边框或填充在一些其他元素的画布周围,并添加填充和或边框到外部元素。

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

[...document.querySelectorAll('canvas')].forEach((canvas) => {
const ctx = canvas.getContext('2d');
ctx.canvas.width  = ctx.canvas.clientWidth;
ctx.canvas.height = ctx.canvas.clientHeight;
let count = 0;


function draw(e, radius = 1) {
const pos = {
x: e.offsetX * canvas.width  / canvas.clientWidth,
y: e.offsetY * canvas.height / canvas.clientHeight,
};
document.querySelector('#debug').textContent = count;
ctx.beginPath();
ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);
ctx.fillStyle = hsl((count++ % 100) / 100, 1, 0.5);
ctx.fill();
}


function preventDefault(e) {
e.preventDefault();
}


if (window.PointerEvent) {
canvas.addEventListener('pointermove', (e) => {
draw(e, Math.max(Math.max(e.width, e.height) / 2, 1));
});
canvas.addEventListener('touchstart', preventDefault, {passive: false});
canvas.addEventListener('touchmove', preventDefault, {passive: false});
} else {
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mousedown', preventDefault);
}
});


function hsl(h, s, l) {
return `hsl(${h * 360 | 0},${s * 100 | 0}%,${l * 100 | 0}%)`;
}
.scene {
width: 200px;
height: 200px;
perspective: 600px;
}


.cube {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
animation-duration: 16s;
animation-name: rotate;
animation-iteration-count: infinite;
animation-timing-function: linear;
}


@keyframes rotate {
from { transform: translateZ(-100px) rotateX(  0deg) rotateY(  0deg); }
to   { transform: translateZ(-100px) rotateX(360deg) rotateY(720deg); }
}


.cube__face {
position: absolute;
width: 200px;
height: 200px;
display: block;
}


.cube__face--front  { background: rgba(255, 0, 0, 0.2); transform: rotateY(  0deg) translateZ(100px); }
.cube__face--right  { background: rgba(0, 255, 0, 0.2); transform: rotateY( 90deg) translateZ(100px); }
.cube__face--back   { background: rgba(0, 0, 255, 0.2); transform: rotateY(180deg) translateZ(100px); }
.cube__face--left   { background: rgba(255, 255, 0, 0.2); transform: rotateY(-90deg) translateZ(100px); }
.cube__face--top    { background: rgba(0, 255, 255, 0.2); transform: rotateX( 90deg) translateZ(100px); }
.cube__face--bottom { background: rgba(255, 0, 255, 0.2); transform: rotateX(-90deg) translateZ(100px); }
<div class="scene">
<div class="cube">
<canvas class="cube__face cube__face--front"></canvas>
<canvas class="cube__face cube__face--back"></canvas>
<canvas class="cube__face cube__face--right"></canvas>
<canvas class="cube__face cube__face--left"></canvas>
<canvas class="cube__face cube__face--top"></canvas>
<canvas class="cube__face cube__face--bottom"></canvas>
</div>
</div>
<pre id="debug"></pre>

使用canvas.getBoundingClientRectevent.clientXevent.clientY的工作示例

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.canvas.width  = ctx.canvas.clientWidth;
ctx.canvas.height = ctx.canvas.clientHeight;
let count = 0;


function draw(e, radius = 1) {
const rect = canvas.getBoundingClientRect();
const pos = {
x: (e.clientX - rect.left) * canvas.width  / canvas.clientWidth,
y: (e.clientY - rect.top) * canvas.height / canvas.clientHeight,
};
ctx.beginPath();
ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);
ctx.fillStyle = hsl((count++ % 100) / 100, 1, 0.5);
ctx.fill();
}


function preventDefault(e) {
e.preventDefault();
}


if (window.PointerEvent) {
canvas.addEventListener('pointermove', (e) => {
draw(e, Math.max(Math.max(e.width, e.height) / 2, 1));
});
canvas.addEventListener('touchstart', preventDefault, {passive: false});
canvas.addEventListener('touchmove', preventDefault, {passive: false});
} else {
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mousedown', preventDefault);
}


function hsl(h, s, l) {
return `hsl(${h * 360 | 0},${s * 100 | 0}%,${l * 100 | 0}%)`;
}
canvas { background: #FED; }
<canvas width="400" height="100" style="width: 300px; height: 200px"></canvas>
<div>canvas deliberately has differnt CSS size vs drawingbuffer size</div>

我正在创建一个应用程序,在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 )
};