【问题标题】:Two canvas above each others return different x,y coordination彼此上方的两个画布返回不同的 x,y 坐标
【发布时间】:2018-07-19 21:01:26
【问题描述】:

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

【问题讨论】:

  • 每个画布从左上角开始都有自己的坐标系。你问的是这个吗?
  • 你需要从鼠标位置减去画布的偏移量得到本地画布位置

标签: javascript canvas html5-canvas


【解决方案1】:

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

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>

【讨论】:

  • clientX - offsetLeft 很遗憾没有考虑到滚动 => 你的示例 sn-p 在我的小屏幕上坏了。
  • @Kaiido 我已经更新了添加滚动的答案。
猜你喜欢
  • 2017-11-16
  • 2015-04-18
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
相关资源
最近更新 更多