Javascript 使鼠标坐标相对于<;帆布>;协调
我试图找到鼠标在画布“网格”上的位置,同时保持大小可调。我现在有鼠标在屏幕上的坐标(x和y) 问题是,WebGL(我正在画布上绘制)和鼠标坐标之间的“缩放”是不同的。WebGL认为从原点向右的10个单位实际上被认为是距离原点的x个单位数(不同的屏幕分辨率会改变这一点)。这意味着当我的鼠标位于WebGL所考虑的(10,10)上方时,我的鼠标坐标为(100100) 如何将屏幕上的鼠标坐标转换为用于定义点的“WebGL坐标”Javascript 使鼠标坐标相对于<;帆布>;协调,javascript,html,canvas,webgl,Javascript,Html,Canvas,Webgl,我试图找到鼠标在画布“网格”上的位置,同时保持大小可调。我现在有鼠标在屏幕上的坐标(x和y) 问题是,WebGL(我正在画布上绘制)和鼠标坐标之间的“缩放”是不同的。WebGL认为从原点向右的10个单位实际上被认为是距离原点的x个单位数(不同的屏幕分辨率会改变这一点)。这意味着当我的鼠标位于WebGL所考虑的(10,10)上方时,我的鼠标坐标为(100100) 如何将屏幕上的鼠标坐标转换为用于定义点的“WebGL坐标” 这与类似,但我不想使用Fabric.js。如果事件侦听器位于canvas元素
这与类似,但我不想使用Fabric.js。如果事件侦听器位于canvas元素上,那么坐标应该已经位于canvas元素上。这意味着mouse.x=0 mouse.y=0将位于画布的左上角。如果事件侦听器位于画布元素上,则坐标应该已经位于画布上。意味着鼠标.x=0鼠标.y=0将位于画布的左上角。要将画布鼠标坐标转换为
-1
到+1
范围内的相对坐标,首先需要使用获取画布内的相对像素坐标
然后将其除以画布的实际宽度和高度,使用
使相对坐标在0
到1
的范围内,我们现在可以通过乘以2
并减去1
将它们移动到正确的范围内
请注意,在WebGL中,上轴为正1
,因此需要反转Y坐标
所有这些加在一起:
var ndcX = (mouseEvent.offsetX / canvas.clientWidth) * 2 - 1;
var ndcY = (1 - (mouseEvent.offsetY / canvas.clientHeight)) * 2 - 1;
要将画布鼠标坐标转换为
-1
到+1
范围内的相对坐标,首先需要使用获取画布内的相对像素坐标
然后将其除以画布的实际宽度和高度,使用
使相对坐标在0
到1
的范围内,我们现在可以通过乘以2
并减去1
将它们移动到正确的范围内
请注意,在WebGL中,上轴为正1
,因此需要反转Y坐标
所有这些加在一起:
var ndcX = (mouseEvent.offsetX / canvas.clientWidth) * 2 - 1;
var ndcY = (1 - (mouseEvent.offsetY / canvas.clientHeight)) * 2 - 1;
看起来这可能有用。让我再做一点测试,但看起来不错。这不起作用。画布中的10个单位宽是onmousmove事件侦听器报告的20多个单位,即使在画布元素上也是如此。由于mouse.x/y返回的值与event.clientX/y相同,这意味着坐标将相对于视口而不是元素。并非所有浏览器都支持x/y。看起来这可能有用。让我再做一点测试,但看起来不错。这不起作用。画布中的10个单位宽是onmousmove事件侦听器报告的20多个单位,即使在画布元素上也是如此。由于mouse.x/y返回的值与event.clientX/y相同,这意味着坐标将相对于视口而不是元素。并非所有浏览器都支持x/y。Ref:添加了webgl标记Ref。注释默认NDC空间(无任何转换)在屏幕左侧为x=-1,右侧为x=+1;y=-1位于屏幕底部,y=+1位于屏幕顶部。我的问题是如何将视口中的光标坐标转换为NDC空间中的光标坐标。或者使用基本数学:
mx=(mouseEvent.offsetX/canvas.clientWidth)*2-1
与y相同,使用offsetY
和clientHeight
添加了webgl标记参考注释默认NDC空间(无任何转换)在屏幕左侧为x=-1,右侧为x=+1;y=-1位于屏幕底部,y=+1位于屏幕顶部。我的问题是如何将视口中的光标坐标转换为NDC空间中的光标坐标。或者使用基本数学:mx=(mouseEvent.offsetX/canvas.clientWidth)*2-1
使用offsetY
和clientHeight
与y相同,但在正常情况下,您的解决方案在ndcY
计算中的输入错误较小。您应该通过canvas.clientHeight
而不是canvas.clientWidth
进行分隔。比看起来更难,但在正常情况下,您的解决方案在ndcY
计算中会出现小错误。您应该通过canvas.clientHeight
而不是canvas.clientWidth
进行分隔。