首页 文章

Three.js - 如何慢慢改变相机的方向,直到达到特定的矢量

提问于
浏览
0

我正在使用Three.js来开发360°图片的播放器,我需要一些建议 .

我在场景中创建了一些cliquable网格物体 . 目前,当用户点击网格时,相机的方向会残酷地改变为网格的方向 . (这是通过调用THREE.Camera.lookat()完成的) .

我想要的是,当用户点击时,摄像机从其目标矢量平滑过渡到网格的方向 . 我想相机需要大约1秒才能从当前矢量转到网格方向 .

我已经看到补间是一个库,我们可以用它来动画场景,但我真的不明白它是如何工作的 . 你知道我可以用来实现这个动画吗?如果补间可以帮助我,你能解释补间如何与three.js发挥作用,或者你可以链接一些githubs或者其他吗?

感谢您的反馈 .

2 回答

  • 0

    只是使用Tween.js扩展manthrax的想法

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.set(0, 0, 0);
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    var sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 32, 24), new THREE.MeshBasicMaterial({
      color: "yellow",
      wireframe: true
    }));
    scene.add(sphere);
    
    var raycaster = new THREE.Raycaster();
    var mouse = new THREE.Vector2();
    var startRotation = new THREE.Quaternion();
    var targetRotation = new THREE.Quaternion();
    window.addEventListener("mousedown", onMouseDown, false);
    
    function onMouseDown(event) {
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      raycaster.setFromCamera(mouse, camera);
      let newPosition = raycaster.ray.at(10);
      setPoint(newPosition);
    
      // manthrax's idea + Tween.js
      startRotation.copy(camera.quaternion);
      camera.lookAt(newPosition);
      camera.updateMatrixWorld();
      targetRotation = camera.quaternion.clone();
      camera.quaternion.copy(startRotation);
    
      new TWEEN.Tween(camera.quaternion).to(targetRotation, 1000).easing(TWEEN.Easing.Bounce.Out).delay(250).start();
      // one of benefits of using Tween.js is easings
      // you can find many of them here
      // https://sole.github.io/tween.js/examples/03_graphs.html
    
    }
    
    function setPoint(position) {
      let point = new THREE.Mesh(new THREE.SphereGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
        color: "red",
        wireframe: true
      }));
      point.position.copy(position);
      scene.add(point);
    }
    
    render()
    
    function render() {
      requestAnimationFrame(render);
      TWEEN.update(); // don't forget to put this line into the animation loop, when you use Tween.js
      renderer.render(scene, camera);
    }
    
    body {
      overflow: hidden;
      margin: 0;
    }
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>
    
  • 0

    就像是:

    var targetRotation,startTime,transitionDuration;
    var startRotation = camera.quaternion.clone();
    
    function smoothTransition(newTarget){
        startRotation.copy(camera.quaternion);
        camera.lookAt(newTarget);
        camera.updateMatrixWorld();
        targetRotation = camera.rotation.clone();
        startTime = performance.now();
        transitionDuration = 1000;
    }
    

    在动画中:

    if(startRotation){
        var playTime = (performance.now()-startTime)/transitionDuration;
        if(playTime>1)playTime = 1;
        Quaternion.slerp(startRotation,targetRotation,camera.rotation,playTime);
        camera.updateMatrixWorld();
    }
    

相关问题