I encountered a problem, where I have a three.js scene in angular custom directive, which is in the view. A the top, I have a navigation bar which is always there to provide navigatin and switching between wiews (nothing abnormal yet). Lets say I set up a simple scene (as many times before, but not under the angular), I put a simple cube in the scene, set up camera rotation and other basic stuff. Problem starts when I try to hit that object on mouse down (raycaster works perfectly) but it seems as my coordinate system started from the top of the page (or I dont have any other explanation for that). For better understanding I have a screen here ( http://prntscr.com/6r6pnu ). It seems as if the real mesh of the object was moved up a little and the image of it rendered as shown at the picture. I must yas I googled a lot but there are not really much about angularjs+three.js
renderer set up:
renderer.setSize(window.innerWidth, window.innerHeight);
element[0].appendChild(renderer.domElement);
where element[0] is my custom directive
<input-dir> <canvas> </input-dir>
raycaster set up:
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());
Thank you
I think the problem is that the mouse coordinates are relative to the viewport that your browser is showing. coordinate (0, 0) is in the browser viewports top left corner, and you want it to be in the top left corner of the canvas that the THREE.js scene is rendered to. Since you have a navbar, you have to account for that offset to the top of the screen when getting your mouse coordinates.
To get the offset from the canvas to the edge of the viewport, you can use the canvas.getBoundingClientRect() function. This will return a object with the size of the canvas, and its position relative to the viewport.
To get the canvas that is created by the THREE.js renderer, you can use renderer.domElement. Or you can assign your own canvas to the renderer in the beginning of the program by passing it a canvas.
var canvas = document.getElementById("canvasID");
renderer = new THREE.WebGLRenderer({ canvas: canvas });
and then using this on to get the offset.
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left, // left offset
y: evt.clientY - rect.top //top offset
};
}
you can use this function to get the coordinates of the mouse position relative to the canvas.
hopefully this solves the problem.
ps. i would have asked you to post the code that you are using right now to get the mouse position, but i couldnt comment on your question. it is always good to provide code that you are having problem with when asking a question on stack overflow
EDIT:
You want to get the mouse coordinates right before you want to use them, in other words:
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 );
next question is, how will you get your canvas as an argument to that function?
To try if this works, try making your renderer global (if it is not already). and then call
var mousePos = getMousePos(renderer.domElement, event);
instead. If it works, you'll probobly want to make the renderer private and get the canvas some other way instead (because it is usually bad practice to have unnecesary global variables).
you can get the canvas with DOM methods, getting it by an id or something.
hope this works!