JavaScriptを呼び出しまくるFlash(AS3)の内側 (「HTMLの暴走」解説 ActionScript編)

HTMLの暴走(meltdown3)」における、Flash(ActionScript 3.0)側の解説です。

Flash側は次の様な流れになっています。

  1. iframeや埋め込みFlashなど、動かせなかったり綺麗に動かそうとすると面倒な要素をJavaScriptから取得
  2. 上記要素がある場合、JavaScriptにその要素を非表示にするように指示すると同時にその位置にノイズのアニメーションを設置し、フェードアウトのアニメーションを開始させる
  3. 初音ミクなど、事前に用意した画像からランダムに画像を選択
  4. 選択された画像のピクセル数を計算(完全に透過の部分は除外)
  5. アニメーション対象のHTML要素数JavaScriptから取得
  6. 画像化に必要なピクセル数とアニメーション対象要素数を比較し、画像化に必要な要素数に達していた場合は画像化演出に分岐

画像化演出の場合

  1. 画像化に不要な余り要素をまず画面外に飛ばす
  2. 事前に作っておいたランダムにピクセル情報を返すオブジェクトから、ピクセル情報を取得
  3. 各要素を適当にかっこよく動かしてピクセルに変化させる
  4. 全部終わったら終了演出へ

画像化演出が無い場合

  1. 2種類の動きからランダムに選択
  2. 全部動かし終わったら終了演出へ

タグが飛び回る終了演出

  1. JavaScriptからHTMLで使用されているタグの情報を取得
  2. 右下に表示されるタグの統計情報を作る
  3. タグアニメーションスタート

動く文字の正体

Flashで動かすためにJavaScriptから文字の情報を取得すると同時にHTML側の文字を消しています。そして取得した情報を元に同じ場所にFlashで文字を配置してアニメーションさせています。
そのFlash側で配置した文字は内部的には文字ではなく、ビットマップ画像です。
フォントを埋め込むとファイルサイズが大きくなる、ユーザー環境のデバイスフォントだと融通が利かない。これをクリアするために、描画したデバイスフォントをビットマップにコピーしてスプライトとして利用しています。

ExternalInterface.call()のトラップ

var tagInfos:Array = ExternalInterface.call('function(){return KAZUMiXmeltdown3.tagInfos}');

上記のようにJavaScript側で用意した配列を丸ごと受け取れればよかったのですが、配列が大きいと異常に時間がかかったり、受け取りに失敗したりすることが多発。(だいたい1000以上のオブジェクトの配列で挙動が怪しくなってました)
しかたなくループで一つずつ受け取りました。

ExternalInterface.call()でIEだと必ずnullが返ってくる

Flash自身のタグががDOM操作で追加されたものだとExternalInterface.call()の呼び出しが成功しても戻り値が必ずnullになってしまう現象に遭遇。私だけではなく、どうもそういうものらしい。

参考
苦い開発: ExternalInterface.call 関数の戻値

DIV要素を作り、そのinnerHTMLの中にFlashの埋め込みタグを書き込むことで回避してます。

パズルのピースが崩れるアニメーション

崩れるパズルピース
これはAdobe After Effectsで作ったアニメーションを静止画のシーケンスで出力し、Vector Magic (Desktop版)を使ってベクター化したものをFlashで使っています。
Vector Magic Desktop 動作画面
ベクター化することで容量は小さくなり、拡大縮小しても劣化がなくとても扱い易いくなります。
Flashのオーサリング機能にもビットマップをベクター化する機能はあります。ほとんど直線で構成されているような画像ならこれで十分な場合も多いのですが、曲線が多いとポイント数が膨大になてしまいちょっといまいちです。