1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

ジョブカン事業部のアドベントカレンダー10日目の記事です

9日目の記事は @Larvesta636 さんによる「日報作成&工数出力のGUIアプリつくってみた」でした。執筆おつかれさまでした。
開発したツールで月次業務が軽減されると良いですね!

概要

本稿はAdobe AfterEffects(以下、AfterEffects)で作成したアニメーションをBodymovinとLottieを使用して、ブラウザー上で再生可能なSVGアニメーションとしてHTMLに埋め込むまでを実施してみます。

モチベーション

Webページにアニメーションを追加するとUX向上を期待できます。しかし、GIFアニメやMP4などの動画ファイルではファイルサイズが大きくなり、読み込み速度に影響を与えかねません。また、これらの形式はラスター形式であるため拡大するとジャギー(ギザギザ)が目立ちます。

SVGアニメーションなら軽量でギザギザしないスケーラブルなアニメーションを実現できます。が、凝ったアニメーションは実装に時間がかかり、実装しても正しく描画されないし変更が困難と感じるのはその辺りに触れたご経験があってもなくても共感いただけると思います。
そこで、今回はモーショングラフィックでお馴染みのAfterEffectsとそのプラグインを用いたSVGアニメーションを作ってみます。

それならFlash後継のAnimateでいいじゃないか

とお叱りを受けそうですが、あちらは正直なところ雲行きが怪しい(本体の開発が鈍化、出力が参照するライブラリーが古め)ので、見なかったことにしました。

Lottieなんて聞いたことがない。無名で実績のないライブラリーは怖くて使えない

とも言われそうですが、以下の公式概要ページを見るとAppleやGoogleなど誰もが知っている大手で使用実績があります。

執筆時現在のAppleはWebページ内の動画にMP4を使用していますが、iOS 18のページを開発者ツールで確認すると lottie の文字列を見つけることができます。

じゃあMP4やめて全部Lottieにするわ

Bodymovinは万能ではありません

Bodymovinはサポートしていないアニメーション表現を無視して出力します。特にエフェクトはほとんど使用できないため、使用を諦めるか代替手段で実装する必要があります

例えば動画でよく使われるパーティクル(粒子表現)や複雑な3D表現は(執筆時現在では)できません。サポート状況は以下の公式ページに記載がありますが、設定画面とにらめっこしながら実際に出力してみるのがわかりやすいと思います

できたもの

  • 約2秒のアニメーションです
  • 中央あたりをクリック(タップ)するとアニメーションを再生します
  • 再生中にクリックすると一時停止します
  • 最後まで再生した状態でクリックすると最初から再生します
  • 表示を拡大・縮小してもジャギらないことが実際に確認できると思います

See the Pen LGTM animation example by djwq (@djwq) on CodePen.

前提条件・環境構築

必要なツール・ライブラリ

環境構築手順

  1. AfterEffects をインストール
  2. Bodymovin拡張機能をインストール
    • Adobe ExchangeLottieのGitHubページからもDL可能ですが、aescripts + aeplugins(AfterEffects拡張機能のストアサイト)からのDLを公式では推奨しているようです
      • 金額が$20.00になっていますが、自分で指定できるので$0.00も可能です
      • manager appがあるとインストールが楽です。おすすめです

なお、実行はWebブラウザーで完結するのでNode.jsなどのJavaScript環境は不要です。

実装方法

AfterEffectsでアニメーションを作成

Lottieを使う前にまずアニメーション本体を作成します。

詳細な作り方を省いても長くなったので折りたたみました
  1. 新しいコンポジションを作成してサイズとフレームレートを設定します
    • とりあえず400px*400px, 60fpsにしました
  2. LGTMを配置します。文字は独立してアニメーションさせるので、単一のテキストレイヤーではなくバラバラに配置します
    • フォントはQuicksand Boldにしました。いい感じにころんとしていてかわいいです
      • 余談ですが実はGoogle Fontsの一部です。知らなかった...
  3. 4つのテキストレイヤーそれぞれからシェイプレイヤーを作成します
    • テキストレイヤーのままではユーザー環境にフォントを要求するため、未インストールの環境では何も表示されません(n敗)
    • これを回避するため、テキストデータをベクターデータに変換して図形として扱うようにします
  4. アニメーションを設定していきます。この作例は色の変化を除くとトランスフォームで完結します
    • L ... 位置回転をアニメーションします
    • G ... 回転を設定しておき位置をアニメーションします。落下時は縦長、衝突時に横長になるようスケールを適度に設定します。アニメーション後半で回転を戻します
      image.png←落下時 地面衝突時→image.png
    • T ... アンカーポイントを中央下に設定しておきスケールをアニメーションします。スケールが最高地点になったら位置もアニメーションさせます
    • M ... 3Dレイヤーを設定しておき、Y回転をアニメーションします。90°を設定してもきれいに隠れないので、回転がはじまるまでは不透明度0%にしています
    • 後半でシェイプの塗り#62A365に設定します
    • 基本的にキーフレームにはイージーイーズを設定しておきます
    • 必要に応じてグラフエディターで速度調整して動きに緩急をつけます
      • 感覚ですが、速→遅にしておくといい感じになります
    • タイムラインは以下のようになりました。スケールをアニメーションしているヌルオブジェクトは、シェイプレイヤーに設定すれば不必要かもしれません
      image.png

BodymovinでJSONファイルをエクスポート

AfterEffectsでアニメーションを作ったら、次にJSONファイルへエクスポートします。

  1. AfterEffectsのメニューからウィンドウ > エクステンション > Bodymovinを選択します

  2. エクスポートしたいコンポジションにチェックを入れます(独自UIでややわかりにくいですが)
    image.png

    • Settingsを開いてDemoにチェックしておくとブラウザーで確認できるHTMLファイルも出力します。Saveで設定を保存します。以下は設定例です
      image.png
  3. 出力フォルダを指定します

  4. Renderボタンをクリックして、JSONファイルを出力します

出力フォルダの設定を行いましたか?

手順3も必須です。筆者はこれを忘れてRenderボタンが押せず、小一時間溶かしました

出力が成功すると以下のような表示になります

image.png

HTMLにアニメーションを組み込む

JSONファイルにエクスポートしたら、コードを書いて実際にアニメーションさせます。

完成形のコードを見たい

コード全文は上記サンプルのHTML, CSS, JSタブより参照いただけます

HTML

Lottieライブラリの読み込みます。
手っ取り早く確認するにはCDNのJSを読み込むのが良いと思います

<script src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js"></script>

アニメーションを描画する要素を用意します。
サイズはCSSで指定するので、ここでは要素の配置のみとします。JavaScriptから要素を参照するのでid属性を正しく設定しておくとよいかなと思います

<div id="lottie"></div>

CSS

描画する要素のサイズを指定します。
スケーラブルなのでいくつでもよいですが、とりあえずコンポジションと同じく400px*400pxにします。ついでに見た目をよくするためmarginでセンタリングします

div#lottie {
    width: 400px;
    height: 400px;
    margin: 0 auto;
}

JavaScript

Bodymovinが出力したJSONを記述します。
ファイルからロードできればそれもよいですが、外部サーバーを用意するのは面倒なので愚直にdata.jsonを展開します

const data = {...};    // data.jsonの中身

続いて初期化をします。アニメーションを描画する要素の決定とアニメーションの読み込みを行います。
特に設定していないと自動再生するので autoplay: false を設定します。さらにloop: false を設定してループ再生は無効にします(画面がうるさくなるので)

// 描画要素を取得
const lottieContainer = document.querySelector("#lottie");

// アニメーション初期化
const animation = lottie.loadAnimation({
  container: lottieContainer, // 描画する要素
  animationData: data, // エクスポートしたJSON
  autoplay: false, // 自動再生
  loop: false // ループ再生
});

描画する要素とアニメーションにコールバック関数を設定します。アニメーションが再生中かの情報は取得できないようなので自前で管理します

// 再生中?
let playing = false;
// 再生完了?
let completed = false;

// 描画要素のクリックイベント
lottieContainer.onclick = () => {
  if (playing) {
    // 再生中なら一時停止
    playing = false;
    animation.pause();
  } else {
    if (completed) {
      // 再生終了済みなら先頭に戻す
      animation.goToAndStop(0);
      completed = false;
    }

    // 再生
    playing = true;
    animation.play();
  }
};

// アニメーション完了イベント
animation.onComplete = () => {
  playing = false;
  completed = true;
};

これでCodePenのサンプルと同じ動作をするはずです

もう少し実用的な例

文字をアニメーションさせるだけでは実用的な使い方のイメージがしにくいかなと思ったので、無限スクロールで使えそうなアニメーションを作ってみました

  • 画面中央部をクリックするとアニメーションします
  • さらにクリックすると状態遷移します(待機中→処理中→完了→待機中→...)
    • 実際にロードするものがないので、代わりにクリックで擬似的に状態遷移しています

See the Pen Loading Sample by djwq (@djwq) on CodePen.

まとめ

本稿では、AfterEffectsで作成したアニメーションをBodymovinとLottieを使用してWebページに埋め込む方法を解説しました。今回はWebページでしたが、LottieはiOSReact(非公式)など様々な環境で動作するよう移植されています。
また、Lottieは逆再生やスクロール位置に応じたアニメーションなど、本稿では紹介していない機能もあります。ぜひご自身のプロジェクトで活用してみてください。

試してみたいけどAfterEffectsなんて持っていない!という各位は以下のページにあるファイルでLottieを試すことができます(要登録)

さいごに

DONUTSでは一緒に働くメンバーを募集しています。
昨年や今年のアドベントカレンダーをご覧になっておもしろそうな人がいる、自分ならプロダクトをもっとよくできるなどジョインしたいという想いがありましたら、以下のページをご覧ください。お待ちしております。

明日の記事は @imadon2024 さんによる「NetflixのSystem Designを眺めてみた」です。ここまで読んでいただいた各位はNetflixのアーキテクチャーも是非眺めてみてください。

記事は以上です。アドカレ初投稿の鳩(@djwq)でした。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?