TrackballControls - zoom by cursor calculation explanation

In order to make zooming into the cursor we do this code,

  1. can someone please explain the part of the calculation when we unproject and sub, I delimited the part in comments? (in addition, I’ve tried to understand what unproject means according the documentary but I still don’t get it).

  2. Why the zoom vector (let vector variable) has z=0.5 and not z=0?

     controls.domElement.addEventListener('wheel', event => {
     const { clientWidth, clientHeight } = controls.domElement;
     const rect = controls.domElement.getBoundingClientRect();
     const x = ((event.clientX - rect.left) / clientWidth ) * 2 - 1;
     const y = -((event.clientY - / clientHeight ) * 2 + 1;
     let vector = new THREE.Vector3(x, y, 0.5);
     // Can someoone explain this part of calculation
     // till here
     const factor = 20;
     if (event.deltaY < 0) {
         camera.position.addVectors(camera.position, vector.setLength(factor));, vector.setLength(factor));
     } else if (event.deltaY > 0) {
         camera.position.subVectors(camera.position, vector.setLength(factor));, vector.setLength(factor));

The docs say about this method: Projects this vector from the camera’s normalized device coordinate (NDC) space into world space. So it’s all about transforming a vector from one coordinate space to another one. If you are not familiar with coordinate spaces, I suggest you read a bit about this topic since there are many existing resources. It would be asked to much to explain everything in a single post.

vector represents a point in 3D space. The above subtraction results in a new vector which points from the camera’s position to the mentioned point. If you compute its length, it’s the actual distance between both points.

This value is some sort of best practice. You can read more about it here: