Three.js:无法设置最大和最小缩放级别

时间:2017-08-20 00:15:20

标签: javascript three.js webgl

我将此示例用于我的WebGL全景多维数据集: https://threejs.org/examples/?q=pano#webgl_panorama_equirectangular

我想在限制范围内放大和缩小,即设置最大和最小缩放级别,但不是默认情况下代码提供的无限级。对于无限缩放,如果滚动太多则稍后会反转视图,上面示例中的函数如下所示:

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

为了解决这个问题,我试图在允许的范围内更新FOV:

    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();
        };
    }

请注意我的FOV是90:

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

这似乎完全适用于最大放大级别 - 当FOV为5时它会停止并且不会进一步放大。然而,当我缩小到FOV 95时,它会停止,但如果我继续使用鼠标缩小,我会再次无限缩放,即使FOV仍为95.

如何停止/控制无限缩小?

1 个答案:

答案 0 :(得分:3)

您的代码在下面的最小示例中按预期工作。 (我确实做了一些小改动,因为我使用>= / <=而不是> / <。)

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();
    })
  })
})();

其他一些东西正在改变相机的数据。您确定没有在任何地方更新camera.zoom吗?

对于它的价值,修改FOV的唯一其他(核心)three.js方法是PerspectiveCamera.setFocalLength

根据新信息进行修改

啊,这是你的问题。我不知道你使用的是外接鼠标控制器。 OrbitControls不会调整FOV来创建缩放效果。相反,它确实将相机移近控件的target更近/更远。你的放大可能(偶然)对应它达到0距离。但是因为它可以缩小到无穷大,这就是它继续缩小的原因。

在评论中禁用缩放可以解决问题。

three.js r87