4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

株式会社ACCESSAdvent Calendar 2024

Day 3

Babylon.jsでイージングを組み合わせたアニメーション

Last updated at Posted at 2024-12-02

はじめに

2024年11月に行われていた技術書典17で、Babylon.js 勉強会さんの Babylon.js レシピ集 Vol.1~5 を購入しました。

一通り目を通し、次は自分で色々試してみたので、そこで知ったことをTipsとして書きました。

イージングについて

前記レシピ集の執筆陣になっている方の解説を参照してください。
Unityではアニメーションカーブをイメージしてもらえればわかりやすいと思います。

簡単に言うと、移動のような動きや色の変化など緩急をつけてあげる機能です。

イージングしながらノードを往復させる

UnityAnimePanel.png

Unityのアニメーションのパネルです。こんな感じの動きをさせようと思います。

公式サンプル

公式のサンプルを一部抜粋します。

keysBezierTorusにキーフレームの座標を設定しています。イージングはsetEasingFunction()に設定しています。この方法ですと、120フレーム目の場所に移動したあと、0フレームに戻ってリピートするため見た目がワープしてしまいます。

    // Torus
    var bezierTorus = BABYLON.Mesh.CreateTorus("torus", 8, 2, 32, scene, false);
    bezierTorus.position.x = 25;
    bezierTorus.position.z = 0;

    // Create the animation
    var animationBezierTorus = new BABYLON.Animation("animationBezierTorus", "position", 30, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
    var keysBezierTorus = [];
    keysBezierTorus.push({ frame: 0, value: bezierTorus.position });
    keysBezierTorus.push({ frame: 120, value: bezierTorus.position.add(new BABYLON.Vector3(-80, 0, 0)) });
    animationBezierTorus.setKeys(keysBezierTorus);
    var bezierEase = new BABYLON.BezierCurveEase(0.32, -0.73, 0.69, 1.59);
    animationBezierTorus.setEasingFunction(bezierEase);
    bezierTorus.animations.push(animationBezierTorus);
    scene.beginAnimation(bezierTorus, 0, 120, true);

サンプルコードを改変して往復させてみる

往復するには、キーフレームの定義のほうにイージングを指定することで可能です。
先にeasingFunctionを作っておきます。ここではBABYLON.SineEase()にしてみました。
setEasingModeBABYLON.EasingFunction.EASINGMODE_EASEINOUTにしました。ゆっくり動き出し、中間で一番速くなり、ゆっくり止まるようになります。

つぎにkeysTorusにキーフレームを定義します。このとき、easingFunctioneasingFunctionを設定することができます。ここでは、0フレームにイージングを設定、移動先の120フレーム目で一旦止まるのでまたイージングを設定しています。240フレームで最初の場所に戻ります。

Playgroundの方に上げたので、よければイージングの種類を変えたりキーフレームを増やしたりして試してみてください。

swing.gif

const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);

const createScene = () => {
    var scene = new BABYLON.Scene(engine);

    var camera = new BABYLON.ArcRotateCamera("Camera",
        0, 0.8, 100, BABYLON.Vector3.Zero(), scene);

    camera.attachControl(canvas, true);

    const light = new BABYLON.HemisphericLight("light",
        new BABYLON.Vector3(1, 1, 0), scene);

    // Torus
    var torus = BABYLON.MeshBuilder.CreateTorus("torus",
        {thickness: 2, tessellation: 32, diameter: 8}, scene);
    torus.position.x = 25;
    torus.position.z = 30;

    const animationTorus = new BABYLON.Animation("torusEasingAnimation",
        "position", 30, BABYLON.Animation.ANIMATIONTYPE_VECTOR3,
        BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

    const easingFunction = new BABYLON.SineEase();
    easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);

    // Animation keys
    const nextPos = torus.position.add(new BABYLON.Vector3(-80, 0, -80));

    const keysTorus = [];
    keysTorus.push({ frame: 0,   value: torus.position, easingFunction: easingFunction });
    keysTorus.push({ frame: 120, value: nextPos,        easingFunction: easingFunction });
    keysTorus.push({ frame: 240, value: torus.position });
    animationTorus.setKeys(keysTorus);

    scene.beginDirectAnimation(torus, [animationTorus], 0, 240, true);

    return scene;
}

const scene = createScene();
engine.runRenderLoop(() => { scene.render();});
window.addEventListener("resize", () => { engine.resize(); });

さいごに

メダル落としを作ってみました。プッシャーが前後に動くところにイージングを使ってます。

ちなみに、AndroidのChromeでARモードにすることができます。 先に chrome://flags でWebXRの設定を有効にする必要があるかもしれません。

PushMedal.png

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?