问题
I created a scene with multiple objects in the canvas element with ThreeJS. I now want to change the material color of an object if the user clicks on it.
Excerpt of my Angular 5 component, which holds all the ThreeJS content:
public onMouseDown(event: MouseEvent) {
console.log("onMouseDown");
event.preventDefault();
var rayCaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
mouse.x = (event.clientX / this.renderer.domElement.clientWidth) * 2 - 1;
mouse.y = -(event.clientY / this.renderer.domElement.clientHeight) * 2 + 1;
rayCaster.setFromCamera(mouse, this.camera);
var intersects = rayCaster.intersectObjects(this.scene.children);
console.log("Scene has " + obj.length + " objects");
console.log(intersects.length + " intersected objects found");
intersects.forEach((i) => {
i.object.material =
new THREE.MeshBasicMaterial({color: 0xf1f11f});
});
this.render();
}
The problem is that the mouse coordinates are not correct, due to the distance between canvas element and the document outer edge. Whenever I click in the scene, an object right of the mouse will get the new material color.
Some information:
this.renderer.domElement.clientWidth holds the width of the canvas element
How to calculate the correct mouse coordinates if the canvas element isn't full screen?
回答1:
If your flow is broken (your container is floated or manually positioned), then clientX/clientY will report "bad" values (relative to the page, rather than to the container like you might expect). The properties offsetX/offsetY account for this by reporting values relative to the container on which the event was fired.
According to MDN, support is limited, but my testing just now (01/22/2018) showed the latest versions of Chrome, Firefox, Edge, and IE all reported the correct values*. Just note that some browsers report integer values, while others may report double values.
*This may not hold true for Safari or mobile browsers. YMMV.
来源:https://stackoverflow.com/questions/48381816/threejs-raycaster-doesnt-find-intersected-objects-if-canvas-isnt-full-screen