8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Adobe Animateで作ったCreateJS形式コンテンツをWebGL再生したい

Last updated at Posted at 2020-09-07

はじめに

Flash、ついに終わりますね(悲しみ)

3年前、同じようなコンセプトでこんなものを作ったんですが、
Adobe Animateのバージョンが上がり、書き出されるコンテンツの構造が変わっていたりするので

Creap.jsの進化版
Adobe Animate製CreateJSコンテンツを、pixi.jsで再生するプラグイン
pixi-animate-player

を改めて作ってみました。

目指すのはCreap.jsと同様

  • アニメーションをAnimateで作りたい
  • でも動作速度は改善したい

です。

ドキュメントとサンプル

使いかた

用意するもの

  • CreateJS 1.0.0
  • pixi.js 5.3.2
  • pixi-animate-player 2.1.2
  • Adobe Animateでパブリッシュしたコンテンツ一式

ファイルの読み込み

<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
<script src="pixi.5.3.2.min.js"></script>
<script src="pixi-animate-player.min.js"></script>
<script src="content/content.js"></script> <!-- Adobe Animateでパブリッシュしたコンテンツ一式のjsファイル -->
  1. 最初にpixi.js及びCreateJS(順不同)
  2. 次にpixi-animate-player
  3. 最後にcontent/content.js

という順で読み込むようにしてください。

実行

var player = new PIXI.animate.Player(
    "[conposition id]", // "lib.properties.id" in Animate content.
    "[root class name]", // Root class name of Animate content.
    "[content directory path]", // Directory path of Animate content.
    {
        useSynchedTimeline: true,
        useMotionGuide: false
    },
    {
        antialias: true
    } // Options of PIXI.Application.
);

player
    .prepareAsync({
        crossOrigin: false
    })
    .then(function() {
        player.play();
    });
  • [conposition id]
    content.js内でlib.properties.idとして定義されている32文字くらいの文字列。

  • [root class name]
    rootに該当するMovieClipクラス名。
    Animateが勝手に付けるので、大体はflaファイルと同名になっているはず。
    (content.flaであれば content

  • [content directory path]
    「Adobe Animateでパブリッシュしたコンテンツ一式ディレクトリ」の
    HTMLから見た相対パス、または絶対パスのいずれか。
    絶対パスを使用、かつアセットが別サーバにある場合は、player.prepareAsyncの引数のcrossOrigintrueにする。

プラグイン自体にPromise polyfillは含めていないので、
必要があれば別途読み込んでください。

パフォーマンス

ここBenchmarksを見てもらえると分かりますが、
ざっくりと重い処理になればなるほど効果が高いといって差し支えないかなと思います。

例として、私のPCでのFPSは

CreateJS pixi-animate-player(webGL) pixi-animate-player(canvas)
100インスタンス 60 60 60
1000インスタンス 52 60 56
1000インスタンス(着色) 42 58 -
5000インスタンス 12 25 14

のような感じで、基本的にはwebGLの力での高速化が大きく、
加えてpixi.jsのレンダリング処理の最適化も若干利いているという感じでしょうか。

本来pixi.jsであれば、5000インスタンス程度ではFPSは下がらないんですが、
タイムライン+入れ子という構造が処理に強く影響しているような印象です。

仕組み

ここからは内部構造についてちょっと。
使えればいいよって方は読み飛ばしてください。

処理フロー

CreateJSの処理フローはざっくりと

  1. アセットのプリロードやらをして
  2. ティッカーが回って
  3. プロパティが変化して
  4. レンダリングされて
  5. 2に戻る

animate.png

のような形です。

pixi-animate-playerでは、このフローが

  1. CreateJSのアセットのプリロードやらをしつつpixi.jsの準備をして
  2. CreateJSのティッカーが回って
  3. CreateJSのプロパティが変化すると同時にpixi.jsのプロパティも変化して
  4. pixi.jsでレンダリングされて
  5. 2に戻る

core.png

のようになっています。

ユーザスクリプト(flaファイル上でタイムラインに実装するスクリプト)は、
そのほとんどが描画内容を変化させるために実装しているものですので、
最終的な描画内容が確定するまではCreateJSに任せてしまい、
レンダリングだけpixi.jsで横取りすればいいや、という考え方です。

本来はCreateJSを完全にエミュレートした方が処理量が少なくなるのですが、
全てのクラスを完全に実装しない限り、ユーザスクリプトに対応しきれない部分があったので
このような形を採っています。

唯一、ユーザのインタラクションイベント(タップなど)だけは、
イベントを受けるのがpixi.jsのオブジェクトになるため、ひと手間加えた処理をしています。

プラグインの構造

上記フローを実現するために

  • createjs.DisplayObject継承クラスのインスタンス1つ(以下A)につき
    PIXI.DisplayObject継承クラスのインスタンスを1つ(以下B)、対になるように生成、
    (e.g. createjs.MovieClip -> PIXI.Container)

  • Aのプロパティが変化すると同時に、Bの対応するプロパティを変化させる
    (e.g.A.scaleX -> B.scale.x)

  • Bが受けたインタラクションを、Aに対するインタラクションとして処理する
    (e.g. ユーザアクション -> B.emit('pointerdown') -> A.dispatchEvent('mousedown'))
    ※これはイメージで、実際には登録されたハンドラを実行しているだけ

といったことをしています。

おわりに

端末の性能も向上してきたので、Animate製CreateJSコンテンツそのまま再生でも問題ないかもなーと思いつつ
どこかで何かの役に立てばいいなと。

AnimateからのwebGL書き出しはいつになったらスクリプト対応するんですかね?

みんなもAnimate使ってね!

8
7
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
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?