Wawa Sensei logo

アニメーション

Starter pack

アニメーションは、3Dシーンに生命を吹き込むための重要な要素です。アニメーションはユーザーインタラクションスクロールあるいは時間に基づいてトリガーされ、3Dオブジェクトライトカメラに適用されます。

アニメーションを完全にマスターすることは、没入感のある体験を作成するためのキーとなります。多くのテクニックを知っているほど、より多くの創造力を発揮することができます。

注意: 3D モデルのアニメーションについては、モデル章でカバーされています。

Lerp

Lerpは、二つの値を補間するための数学関数です。これは、一つの点から他の点まで値をアニメートするのに役立ちます。

const value = THREE.MathUtils.lerp(start, end, t);

第一引数開始値第二引数終了値、そして第三引数0から1までの補間係数です。

補間係数0に近いほど、アニメーションはゆっくりになります。補間係数1に近いほど、アニメーションはより速く終了値または目標値に達します。

スターターパックAnimatedBox コンポーネントでこれを試してみましょう。

このコンポーネントには、異なる時間におけるボックス位置が格納された boxPositions 配列があります。useFrame フックを追加して、時間に基づいてボックス位置更新しましょう:

import { RoundedBox } from "@react-three/drei";
import { useRef } from "react";

export const AnimatedBox = ({ boxPositions, ...props }) => {
  const box = useRef();

  useFrame(({ clock }) => {
    const seconds = parseInt(clock.getElapsedTime());
    const targetPosition = boxPositions[seconds % boxPositions.length];

    box.current.position.x = targetPosition.x;
    box.current.position.y = targetPosition.y;
    box.current.position.z = targetPosition.z;
  });
  // ...
};

ここではボックスがアニメートされていません。位置から位置へとテレポートします。lerp 関数を使ってそれをアニメートしてみましょう:

import * as THREE from "three";
// ...

export const AnimatedBox = ({ boxPositions, ...props }) => {
  const box = useRef();

  useFrame(({ clock }) => {
    const seconds = parseInt(clock.getElapsedTime());
    const targetPosition = boxPositions[seconds % boxPositions.length];
    box.current.position.x = THREE.MathUtils.lerp(
      box.current.position.x,
      targetPosition.x,
      0.05
    );
    box.current.position.y = THREE.MathUtils.lerp(
      box.current.position.y,
      targetPosition.y,
      0.05
    );
    box.current.position.z = THREE.MathUtils.lerp(
      box.current.position.z,
      targetPosition.z,
      0.05
    );
  });
  // ...
};

ボックス滑らかに移動するようになりました。

Vector3 クラスには lerp メソッドがあり、THREE.MathUtils.lerp 関数の代わりに使用できます:

// box.current.position.x = THREE.MathUtils.lerp(
//   box.current.position.x,
//   targetPosition.x,
//   0.05
// );
// box.current.position.y = THREE.MathUtils.lerp(
//   box.current.position.y,
//   targetPosition.y,
//   0.05
// );
// box.current.position.z = THREE.MathUtils.lerp(
//   box.current.position.z,
//   targetPosition.z,
//   0.05
// );
box.current.position.lerp(targetPosition, 0.05);

同じ結果を得るためにたくさんの行を削減できますね!

時間を調整したり、rotationscale などの他のプロパティに lerp を適用して異なる効果を試してみてください。

Float

Float は、オブジェクトが浮いている印象を簡単に与えるための Drei library からの ラッパーコンポーネント です。

以下のプロパティを含みます:

  • speed: アニメーションの速度、デフォルトは1
  • rotationIntensity: XYZ回転の強度、デフォルトは1
  • floatIntensity: 上下の浮動強度、floatingRangeとの乗算として機能、デフォルトは1
  • floatingRange: オブジェクトが浮動するy軸の範囲、デフォルトは[-0.1, 0.1]

Experience.jsxDuck を浮動させましょう:

End of lesson preview

To get access to the entire lesson, you need to purchase the course.