Monday, September 4, 2017

Three.js: Unable to Set Maximum and Minimum Zoom Level

Leave a Comment

I am using this example for my WebGL panorama cube: https://threejs.org/examples/?q=pano#webgl_panorama_equirectangular

I want to zoom in and out within limits, i.e. set maximum and minimum zoom level, but not infinitely as code provides by default. For infinite zoom, which later reverses the view if scrolled too much, the function from example above looks like this:

    function onDocumentMouseWheel( event ) {             camera.fov += event.deltaY * 0.05;             camera.updateProjectionMatrix();     } 

To address the issue I tried to update FOV when inside my allowed range:

    function onDocumentMouseWheel( event ) {         var fovMAX = 95;         var fovMIN = 5;         var newFov = camera.fov + event.deltaY * 0.05;         if (newFov > fovMIN && newFov < fovMAX) {             camera.fov = newFov;             camera.updateProjectionMatrix();         };     } 

Please note my FOV is 90:

camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight), 0.1, 100 ); 

This seems to have perfectly worked for maximum zoomed-in level - it stops when FOV is 5 and does not zoom in further. However, as I zoom out to FOV 95, it would stop, but if I continue zooming out with mouse more, I would zoom infinitely again, even though FOV remains 95.

How to stop/control infinite zoom out?

1 Answers

Answers 1

Your code works as expected in the minimal example below. (I did make a small change in that I'm using >=/<= rather than >/<.)

var renderer, scene, camera, controls, stats;    var WIDTH = window.innerWidth,    HEIGHT = window.innerHeight,    FOV = 35,    NEAR = 1,    FAR = 1000;    var fovMax = 95,    fovMin = 5,    fovTmp = 0;    function zoom(event) {    event.preventDefault();    fovTmp = camera.fov + (event.deltaY * 0.05);    if (fovTmp >= fovMin && fovTmp <= fovMax) {      camera.fov = fovTmp;      camera.updateProjectionMatrix();    }  }    function init() {    document.body.style.backgroundColor = "slateGray";      renderer = new THREE.WebGLRenderer({      antialias: true,      alpha: true    });      document.body.appendChild(renderer.domElement);    document.body.style.overflow = "hidden";    document.body.style.margin = "0";    document.body.style.padding = "0";      scene = new THREE.Scene();      camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);    camera.position.z = 50;    scene.add(camera);      var light = new THREE.PointLight(0xffffff, 1, Infinity);    camera.add(light);      stats = new Stats();    stats.domElement.style.position = 'absolute';    stats.domElement.style.top = '0';    document.body.appendChild(stats.domElement);      resize();    window.onresize = resize;      // POPULATE EXAMPLE    var cubeGeo = new THREE.BoxBufferGeometry(1, 1, 1),      cubeMat = new THREE.MeshPhongMaterial({        color: "red"      });    var mesh = new THREE.Mesh(cubeGeo, cubeMat);    scene.add(mesh);      window.addEventListener("wheel", zoom);      animate();  }    function resize() {    WIDTH = window.innerWidth;    HEIGHT = window.innerHeight;    if (renderer && camera) {      renderer.setSize(WIDTH, HEIGHT);      camera.aspect = WIDTH / HEIGHT;      camera.updateProjectionMatrix();    }  }    function render() {    renderer.render(scene, camera);  }    function animate() {    requestAnimationFrame(animate);    render();    stats.update();  }    function threeReady() {    init();  }    (function() {    function addScript(url, callback) {      callback = callback || function() {};      var script = document.createElement("script");      script.addEventListener("load", callback);      script.setAttribute("src", url);      document.head.appendChild(script);    }      addScript("https://threejs.org/build/three.js", function() {      addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {        threeReady();      })    })  })();

Something else is changing your camera's data. Are you sure you're not updating camera.zoom anywhere?

For what it's worth, the only other (core) three.js method that modifies the FOV is PerspectiveCamera.setFocalLength

Edit based on new information

Ah, there's your problem. I didn't know you were using an external mouse controller. OrbitControls doesn't adjust the FOV to create its zoom effect. Instead, it literally moves the camera nearer to/further from the control's target. Your zoom-in likely (by chance) corresponded with it reaching 0 distance. But because it can zoom out to infinity, that's why it continued to zoom out.

Disabling zoom like in your comment should resolve the issue.

three.js r87

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment