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

时间:2018-04-11 17:28:50

标签: three.js camera tween.js

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

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

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

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

感谢您的反馈。

2 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分: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>
&#13;
&#13;
&#13;