block by HarryStevens f9a31f69cf7645c34e473c1250b2ab30

Camera Tween

Full Screen

An example of using tween.js to smoothly interpolate the camera’s position. Here’s a list of available easing functions.

index.html

<html>
  <head>
    <style>
      body {
        margin: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div id="stats"></div>
    <div id="scene"></div>

    <script src="https://unpkg.com/three@0.106.2/build/three.min.js"></script>
    <script src="https://unpkg.com/three@0.106.2/examples/js/libs/stats.min.js"></script>
    <script src="https://unpkg.com/tween.js@16.6.0/src/Tween.js"></script>

    <script>
      const stats = (_ => {
        const stats = new Stats();
        stats.domElement.style.position = "absolute";
        stats.domElement.style.left = "0px";
        stats.domElement.style.top = "0px";
        document.getElementById("stats").appendChild(stats.domElement);
        return stats;
      })();

      const scene = new THREE.Scene();

      const positions = [
        [10, 15, 20],
        [-30, 30, -15]
      ];
      let currPosition = 0;

      const camera = (_ => {
        const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 1000);
        camera.position.set(...positions[currPosition]);
        camera.lookAt(scene.position);
        return camera;
      })();

      const renderer = (_ => {
        const renderer = new THREE.WebGLRenderer();
        renderer.setClearColor("#eee");
        renderer.setPixelRatio(devicePixelRatio);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = 2;
        document.getElementById("scene").appendChild(renderer.domElement);
        return renderer;
      })();

      const plane = (_ => {
        const geom = new THREE.PlaneBufferGeometry(60, 60);
        const matl = new THREE.MeshLambertMaterial({ color: "#fff"});
        const plane = new THREE.Mesh(geom, matl);
        plane.rotation.x = -0.5 * Math.PI;
        plane.receiveShadow = true;
        scene.add(plane);
        return plane;
      })();

      const box = (_ => {
        const geom = new THREE.BoxBufferGeometry(4, 4, 4);
        const matl = new THREE.MeshLambertMaterial({ color: "steelblue" });
        const box = new THREE.Mesh(geom, matl);
        box.position.y = 2;
        box.castShadow = true;
        scene.add(box);
        return box;
      })();

      const ambient = (_ => {
        const light = new THREE.AmbientLight("#555");
        scene.add(light);
        return light;
      })();

      const spot = (_ => {
        const light = new THREE.SpotLight("#fff");
        light.position.set(-20, 20, 20);
        light.shadow.mapSize.width = 1024;
        light.shadow.mapSize.height = 1024;
        light.angle = Math.PI / 8;
        light.castShadow = true;
        scene.add(light);
        return light;
      })();

      function animate(){
        requestAnimationFrame(animate);
        stats.update();
        TWEEN.update();
        camera.lookAt(scene.position);
        renderer.render(scene, camera);
      }
      animate();

      function resize(){
        camera.aspect = innerWidth / innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(innerWidth, innerHeight);
      }
      resize();
      onresize = resize;

      function interval(){
        currPosition = currPosition === 0 ? 1 : 0;
        tweenCamera(camera, positions[currPosition], 3000);
      }
      interval();
      setInterval(interval, 4000);

      function tweenCamera(camera, position, duration) {        
        new TWEEN.Tween(camera.position).to({
          x: position[0],
          y: position[1],
          z: position[2]
        }, duration)
        .easing(TWEEN.Easing.Quadratic.InOut)
        .start();
      }
    </script>
  </body>
</html>