みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Three.jsでカメラをスムーズに移動する 🎥


DEMO

kimizuka.org

左上のボタンを押すとカメラの位置がスムーズに移動します。
今回の例だとcubeのscaleを変えるのと見栄えは変わらないですが、しっかりとカメラを動かしています。

ソースコード(抜粋)

const maxRange = 16;
const minRange = 2;

export default function CubePage({ contents }) {
  const targetRef = useRef(maxRange);
  const positionRef = useRef(minRange);
  const canvasRef = useRef(null);
  const { windowWidth, windowHeight } = useResize();
  const { THREE, renderer, camera, scene } = useThree(canvasRef.current);

  useEffect(() => {
    if (!renderer || !camera) {
      return;
    }

    camera.position.set(positionRef.current, positionRef.current, positionRef.current);
    camera.lookAt(new THREE.Vector3(0, 0, 0));

    const cube = new THREE.Mesh(
      new THREE.BoxGeometry(1, 1, 1),
      new THREE.MeshNormalMaterial()
    );

    scene.add(cube);

    renderer.setClearColor(0xFFFFFF, 1);
    renderer.setAnimationLoop(() => {
      positionRef.current += (targetRef.current - positionRef.current) * .02;

      camera.position.set(positionRef.current, positionRef.current, positionRef.current);
      renderer.render(scene, camera);
    });
  }, [renderer, camera]);

  useEffect(() => {
    if (!renderer || !camera) {
      return;
    }

    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(windowWidth, windowHeight);

    camera.aspect = windowWidth / windowHeight;
    camera.updateProjectionMatrix();
  }, [renderer, camera, windowWidth, windowHeight]);

  return (
    <div>
      <MockHead content={ contents[0] } />
      <canvas ref={ canvasRef } />
      <button onClick={ () => targetRef.current = targetRef.current === maxRange ? minRange : maxRange }>move</button>
    </div>
  );
}

useThreeは 以前使ったもの を使っています。

blog.kimizuka.org