返回

Three.js动起来之——动画和移动的摄像机

前端

重获新生:动画的实现

为了实现场景动画,我们需要在特定的时间间隔重新渲染场景。那么,有哪些方法可以做到这一点呢?

方案一:setInterval

setInterval是一个 JavaScript 内置函数,它允许我们在指定的间隔时间执行特定的函数。使用 setInterval 来实现动画非常简单,只需将渲染场景的函数作为参数传递给 setInterval 即可。

setInterval(function() {
  renderer.render(scene, camera);
}, 16);

上面的代码将每 16 毫秒渲染一次场景。这样做的好处是简单易懂,而且兼容性很好。但是,setInterval 的缺点在于它并不精确。由于 JavaScript 是单线程的,当主线程繁忙时,setInterval 可能会跳过一些帧,导致动画不流畅。

方案二:setTimeout

setTimeout 与 setInterval 类似,但它只执行一次指定的函数。我们可以通过递归调用 setTimeout 来实现动画。

function animate() {
  renderer.render(scene, camera);
  setTimeout(animate, 16);
}

animate();

这种方法比 setInterval 更加精确,但它对浏览器性能要求更高。如果浏览器标签处于非激活状态,setTimeout 将不会执行,这会导致动画停止。

方案三:requestAnimationFrame

requestAnimationFrame 是一个 HTML5 API,它允许我们在浏览器渲染每一帧之前执行特定的函数。使用 requestAnimationFrame 来实现动画可以获得最佳的性能和兼容性。

function animate() {
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

animate();

requestAnimationFrame 的工作原理是,它会在浏览器渲染每一帧之前调用指定的函数。这样可以确保动画始终与浏览器的刷新率保持一致,从而获得流畅的动画效果。

镜头下的世界:移动的摄像机

除了场景动画,我们还可以控制摄像机的移动,从而获得更具交互性的场景。

键盘控制

我们可以使用键盘事件来控制摄像机的移动。例如,我们可以使用以下代码来控制摄像机的上下左右移动:

document.addEventListener('keydown', function(event) {
  switch (event.key) {
    case 'w':
      camera.position.y += 1;
      break;
    case 's':
      camera.position.y -= 1;
      break;
    case 'a':
      camera.position.x -= 1;
      break;
    case 'd':
      camera.position.x += 1;
      break;
  }
});

鼠标控制

我们还可以使用鼠标事件来控制摄像机的移动。例如,我们可以使用以下代码来控制摄像机的旋转:

document.addEventListener('mousemove', function(event) {
  camera.rotation.y = event.clientX / window.innerWidth * Math.PI * 2;
  camera.rotation.x = event.clientY / window.innerHeight * Math.PI;
});

结语

通过本文的学习,我们已经掌握了如何使用 Three.js 实现场景动画和移动摄像机。希望这些知识能够帮助你创作出更具交互性和动态性的 Three.js 场景。