'Clicking Objects in three.js when the canvas is not full screen r74

thank you for taking your time to answer my question.

I really can't find a good example on how to use raycaster in three JS in the version r74.

It seems to be a lot of changes between the versions r55 and r76... and many forums are talking and putting examples of minor versions of three..

can anyone give us an example of how to do it?

Im using angular and bootstrap by the way

this is what i've try:

My View

<div class="col-md-11">
  <div class="container">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Title</h3>
      </div>
      <div class="panel-body" style="padding: 0px">
        <div class="canvas-zonas" ng-click="zonas.click($event)">
        </div>
      </div>
    </div>
  </div>
</div>

My Css (using stylus)

.canvas-zonas
  height 67vh

My Controller

var = mouse = new THREE.Vector3();
var = raycaster = new THREE.Raycaster();
var = canvas = document.querySelector(".canvas-zonas");

function clickObject(event) {
      event.preventDefault();
      mouse.x= ((event.clientX - canvas.offsetLeft)/canvas.clientWidth) * 2 - 1;
      mouse.y=-((event.clientY - canvas.offsetTop)/canvas.clientHeight) * 2 + 1;
      mouse.z = 0.5;
      raycaster.setFromCamera( mouse, camera );
      var intersects = vm.raycaster.intersectObjects(scene.children);
      console.info(intersects);
    }

So when I click my canvass and print the Intersects variable, sometimes I get [] an empty array even if a click the object and sometimes I get [object] even if I click outside the object.

I would like to show you guys a little bit of my camera config:

My camera

var camera = new THREE.PerspectiveCamera(30, canvas.clientWidth / canvas.clientHeight, 0.10, 1000)
camera.position.y = 20;
camera.position.z = 50;
camera.lookAt(scene.position);
camera.updateProjectionMatrix();

That's my camera config, and also, have in mind that I use a WEBGL as renderer

var renderer = new THREE.WebGLRenderer({antialias: true});

Also, have in mind that I have a resize event going on:

function listenResize() {
  window.bind('resize', function () {
    canvas = document.querySelector(".canvas-zonas");
    renderer.setSize(canvas.clientWidth, canvas.clientHeight);
    camera.aspect = (canvas.clientWidth / canvas.clientHeight);
    camera.updateProjectionMatrix();
  });
}

And finally, I'll post an image of what's going on:

Image 1

In this case, I clicked inside the object but no objects were recuperated

Image 2 In this case, I clicked outside, and an object were recuperated

thank you very much and excuse my last post. i've updated it!!!



Solution 1:[1]

I had exactly the same problem as you. After spending two days lurking around internet I finally found and tested this with good results:

let canvasBounds = this.renderer.context.canvas.getBoundingClientRect();
this.mouse.x = ( ( event.clientX - canvasBounds.left ) / ( canvasBounds.right - canvasBounds.left ) ) * 2 - 1;
this.mouse.y = - ( ( event.clientY - canvasBounds.top ) / ( canvasBounds.bottom - canvasBounds.top) ) * 2 + 1;

Source: THREE.js Ray Intersect fails by adding div

Credits:

  • Y coordinate - "Kris Roofe" answer.
  • X coordinate - "beepscore" who commented Kris Roofe's answer.

I hope it helps many folks like me.

Solution 2:[2]

Maybe things have changed in the intervening years ... this mapping from mouse to (-1, 1) coordinates works for me despite responsive canvas shrinkage:

mouseVector.x = 2 * (e.x / canvas.offsetWidth) - 1;
mouseVector.y = 1 - 2 * ( (e.y - canvas.offsetTop) / canvas.offsetHeight );
mouseVector.z = 0.5 ;

Note that offsetHeight is NOT the same as height! same for width.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 M. Paulikas
Solution 2 Dharman