当具有渲染器的DOM元素不在屏幕顶部时,移动场景的坐标

时间:2015-04-08 15:25:34

标签: javascript angularjs three.js coordinates raycasting

我遇到了一个问题,我在角度自定义指令中有一个three.js场景,它位于视图中。顶部,我有一个导航栏,总是在那里提供导航和切换wiews(没有异常)。让我说我设置了一个简单的场景(之前很多次,但不是在角度下),我在场景中放置了一个简单的立方体,设置了相机旋转和其他基本的东西。当我尝试在鼠标按下时击中该对象时出现问题(raycaster完美地工作)但似乎我的坐标系从页面顶部开始(或者我没有任何其他解释)。为了更好地理解,我在这里有一个屏幕(http://prntscr.com/6r6pnu)。似乎对象的真实网格向上移动了一点,其图像如图所示呈现。我必须用谷歌搜索很多但是没有太多关于angularjs + three.js

渲染器设置:

 renderer.setSize(window.innerWidth, window.innerHeight);
    element[0].appendChild(renderer.domElement);

其中element [0]是我的自定义指令

<input-dir> <canvas> </input-dir>

raycaster设置:

          var vector = new THREE.Vector3();
      vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
      vector.unproject( camera );

      raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize());

谢谢

1 个答案:

答案 0 :(得分:2)

我认为问题在于鼠标坐标是相对于浏览器显示的视口的。坐标(0,0)位于浏览器视口的左上角,您希望它位于渲染THREE.js场景的画布的左上角。由于您有一个导航栏,因此在获取鼠标坐标时必须考虑到屏幕顶部的偏移量。

要获取从画布到视口边缘的偏移量,可以使用canvas.getBoundingClientRect()函数。这将返回一个具有画布大小的对象及其相对于视口的位置。

要获取由THREE.js渲染器创建的画布,可以使用renderer.domElement。或者,您可以通过将画布传递给画布,将自己的画布分配给程序开头的渲染器。

var canvas = document.getElementById("canvasID");
renderer = new THREE.WebGLRenderer({ canvas: canvas });

然后使用它来获取偏移量。

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left, // left offset
      y: evt.clientY - rect.top //top offset
    };
}

您可以使用此功能获取相对于画布的鼠标位置坐标。

希望这可以解决问题。

PS。我会要求你发布你正在使用的代码来获得鼠标位置,但我不能评论你的问题。在提出有关堆栈溢出的问题时,提供您遇到问题的代码总是很好

编辑: 您希望在想要使用它们之前获取鼠标坐标,换句话说:

var vector = new THREE.Vector3();
var mousePos = getMousePos(canvas, event);
vector.set( ( mousePos.x / window.innerWidth ) * 2 - 1,
 - ( mousePos.y / window.innerHeight ) * 2 + 1, 0.5 );
vector.unproject( camera );

接下来的问题是,你将如何将画布作为该函数的参数? 要尝试这是否有效,请尝试将渲染器设置为全局(如果尚未设置)。然后致电

var mousePos = getMousePos(renderer.domElement, event);

代替。如果它有效,你可能会想要使渲染器变为私有并以其他方式获取画布(因为拥有不必要的全局变量通常是不好的做法)。

你可以使用DOM方法获取画布,通过id或其他方式获取它。

希望这有效!