首页 > 解决方案 > 彼此上方的两个画布返回不同的 x,y 坐标

问题描述

我在彼此上方绘制了 2 个画布,在底部我加载了一个图像。我将顶部画布用于鼠标移动事件,并根据底部画布上加载的图像绘制一些信息(例如,当鼠标在眼睛上方时,我绘制圆圈)。问题是即使两个画布具有相同的宽度和高度,顶部画布的 x,y 的协调似乎不适合底部画布,我错过了什么吗?加载图像后,我尝试将顶部 canvas.scale 设置为波纹管。谢谢!JB

标签: javascriptcanvashtml5-canvas

解决方案


您需要像这样从画布位置中减去当前鼠标位置

let x = e.clientX - canvasA.offsetLeft
let y = e.clientY - canvasA.offsetTop

这样做会给你画布的本地位置而不是窗口的位置。

这是一个示例(将鼠标移到红色画布上):

const canvasA = document.getElementById('a')
const canvasB = document.getElementById('b')

let ctxB = canvasB.getContext('2d')

canvasA.addEventListener('mousemove', e => {
  ctxB.clearRect(0, 0, canvasB.width, canvasB.height)

  // Get the local x/y coordinates of the mouse on the red canvas
  let x = e.clientX - canvasA.offsetLeft
  let y = e.clientY - canvasA.offsetTop

  // Mimic the position on the blue canvas with a white dot
  ctxB.beginPath();
  ctxB.arc(x, y, 5, 0, 2 * Math.PI, false);
  ctxB.fillStyle = 'white';
  ctxB.fill();
})
#a {
  background-color: red;
}

#b {
  background-color: blue;
}
<canvas id="a"></canvas>
<canvas id="b"></canvas>

如果你不计算这个会发生什么,我在身体的顶部添加了填充,你会看到这个点现在50px低于鼠标。

const canvasA = document.getElementById('a')
const canvasB = document.getElementById('b')

let ctxB = canvasB.getContext('2d')

canvasA.addEventListener('mousemove', e => {
  ctxB.clearRect(0, 0, canvasB.width, canvasB.height)

  // Get the local x/y coordinates of the mouse on the red canvas
  let x = e.clientX
  let y = e.clientY

  // Mimic the position on the blue canvas with a white dot
  ctxB.beginPath();
  ctxB.arc(x, y, 5, 0, 2 * Math.PI, false);
  ctxB.fillStyle = 'white';
  ctxB.fill();
})
body {padding-top: 50px;}

#a {
  background-color: red;
}

#b {
  background-color: blue;
}
<canvas id="a"></canvas>
<canvas id="b"></canvas>

如果需要考虑滚动,可以使用document.documentElement.scrollTop

let x = (e.clientX + document.documentElement.scrollLeft) - canvasA.offsetLeft
let y = (e.clientY + document.documentElement.scrollTop) - canvasA.offsetTop

const canvasA = document.getElementById('a')
const canvasB = document.getElementById('b')

let ctxB = canvasB.getContext('2d')

canvasA.addEventListener('mousemove', e => {
  ctxB.clearRect(0, 0, canvasB.width, canvasB.height)

  // Get the local x/y coordinates of the mouse on the red canvas
  let x = (e.clientX + document.documentElement.scrollLeft) - canvasA.offsetLeft
  let y = (e.clientY + document.documentElement.scrollTop) - canvasA.offsetTop

  // Mimic the position on the blue canvas with a white dot
  ctxB.beginPath();
  ctxB.arc(x, y, 5, 0, 2 * Math.PI, false);
  ctxB.fillStyle = 'white';
  ctxB.fill();
})
body {
  padding-top: 150vh;
}

#a {
  background-color: red;
}

#b {
  background-color: blue;
}
<canvas id="a"></canvas>
<canvas id="b"></canvas>


推荐阅读