首页 > 解决方案 > 在 Three.JS 中为场景添加最大移动到 onMouseMove

问题描述

我已经成功地在 three.js 中的场景中添加了一个非常漂亮的鼠标移动,其中相机位于场景内部,面向四堵墙之一。向左或向右移动鼠标可以稍微平移和晃动场景。

但是,如果您一直将鼠标悬停在屏幕的一侧,您最终会“飞”到场景之外,现在从外面查看整个 3D 对象,而不是在里面。

我想知道如何更新下面的代码以限制您可以向左或向右移动的最大数量,这样您就不会出现在场景之外?

如果我可以避免添加另一个库,例如 Orbit Controls,那将是理想的,但如果这是唯一的方法,那么我会这样做。我觉得我已经接近在我的函数 animate() 中添加某种 Math.Max 到相机位置,但到目前为止还没有取得任何成功。

提前感谢您的帮助!

window.addEventListener("load", loadGltf, false);
window.addEventListener("resize", onWindowResize, false);
const progressBar = document.querySelector("progress");

//store our imported glTF scene when loaded successfully
const gltfStore = {};

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.getElementById( 'container' );



//camera
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

camera.position.set(0, 0, 0);
camera.lookAt(0, 0, 5);

windowHalfX = window.innerWidth / 2,
        windowHalfY = window.innerHeight / 2,
        mouseX = 0,
        mouseY = 0;

//re-establish camera view on window resize
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

//lighting
const lightFill = new THREE.PointLight(0xffffff, 1, 500);
lightFill.position.set(0, 0, 5);
scene.add(lightFill);

const lightKey = new THREE.PointLight(0xffffff, 1, 500);
lightKey.position.set(20, 0, 20);
scene.add(lightKey);

const loader = new THREE.GLTFLoader();


function loadGltf() {
  loader.load(
    "<?php echo get_template_directory_uri();?>/objects/SM_LookDev_TextureTest_FromFBX.glb",
    //onLoad
    function(gltf) {
      scene.add(gltf.scene);
       mesh = gltf.scene;
      //set material emissive to 0
      gltf.scene.children[0];
      gltfStore.scene = gltf.scene;
       document.addEventListener("mousemove", onMouseMove);

    }

  );

  container.appendChild(renderer.domElement); 

// Mouse movement

function onMouseMove(event) {

          mouseX = (event.clientX - windowHalfX) / 10;
          mouseY = (event.clientY - windowHalfY) / 30;
}


function getMouseX(event) {
    if (event.type.indexOf("touch") == -1)
        return event.clientX;
    else
        return event.touches[0].clientX;
}

function getMouseY(event) {
    if (event.type.indexOf("touch") == -1)
        return event.clientY;
    else
        return event.touches[0].clientY;
}

  function animate() {
    requestAnimationFrame(animate);


    camera.position.x += (mouseX - camera.position.x) * .0005;
        camera.position.y += (-mouseY - camera.position.y) * .0003;
        camera.lookAt(0,0,10);
    renderer.render(scene, camera);

  }



  animate();


}

标签: three.jsonmousemove

解决方案


Three.js 在其类中附带了一些实用方法MathUtils,可以帮助解决这个问题。您可以使用THREE.MathUtils.clamp来限制 and 的最小值和mouseX最大值mouseY

function onMouseMove(event) {
    mouseX = THREE.MathUtils.clamp((event.clientX - windowHalfX) / 10, -20, 20);
    mouseY = THREE.MathUtils.clamp((event.clientY - windowHalfY) / 30, -10, 10);
}

等的最小值和最大值-20, 20取决于.gltf对象的边界,因此您必须相应地调整它们。

这只是一个辅助方法,它使用 JavaScript 的本机Math.min()Math.max()内部来“钳制”该值。

r112 及更低版本的注意事项:

在 Three.js 版本 113 之前,THREE.MathUtils该类曾经被调用THREE.Math,但这可能会导致与 JavaScript 的原生Math类发生冲突。确保根据您使用的 Three.js 版本使用正确的名称,有关更多详细信息,请参见此处


推荐阅读