ラベル

2015年5月9日土曜日

Edge Animate Tips 4

今回はEdge Animateでのグローバルな変数と関数についてです。
ちょっと難しいですよ。


むやみにグローバルなオブジェクトは作らない

まず、最初に断わっておくと、Edge Animate内でグローバル関数やグローバル変数を使うことは推奨されていません。

というのも、Edge Animateは、一つのHTML内で複数のEdge Animateコンポジション(ファイル全体のこと)を使用されても問題が発生しないように、即時関数とクロージャで包まれた形に設計されています。

さて、ここで重要なのが「Edge Animateの各シンボルは即時関数で包まれている」ということです。
しかも、その即時関数が並列に置かれている(たとえステージであっても)ので、あるシンボルから、別のシンボル内の変数を参照することができません。

JavaScriptの変数スコープは上層へしかつながっていないためです。

変数が参照できないということは、関数もまた参照できません。
あるシンボル内で書いた関数は、別のシンボルから呼び出せないのです。

setVariableとgetVariable


これは流石に困りますよね。
でも、Adobeが推奨している解決方法があります。
それがsetVariable()とgetVariable()です。

setVariable()で変数をセットし、getVariable()でゲット、つまり読み込みます。
これはsym.getComposition().getStage().getVariable()のように仮想のパスをつけて参照することができるので、どこのシンボルでもセットでき、また読み込むことが可能です。

これで、多少メンドクサイですが変数はなんとかなりました。
では関数はどうでしょうか?

JavaScriptでは変数に関数の参照を入れることができるので、変数が読み込めるということは関数にもアクセスできるということです。

つまり、こうやって書くと関数を別のシンボルから呼び出せるようになります。

var foo = function () {
  alert('ok');
}
sym.setVariable('myFunction', foo);

これをステージ内のcreateCompleteにでも書けば、myFunctionという名前の関数がステージにセットされます。

あとは別のシンボルから

var bar = sym.getComposition().getStage().getVariable('myFunction');
bar();

と書けば、関数を実行することができます。
長いw

でも、これが唯一、Adobeが推奨する安全な方法なんです。
書くのはメンドクサイですが、Flashライクなオブジェクト指向プログラミングができます。
タイムラインを持ったシンボルをオブジェクトに見立てて、setVariableでプロパティやメソッドを定義するような感じです。

まあ、JavaScriptのテクを駆使すれば、もう少し、楽な書き方もできます。

sym.setVariable('myFunction', function () {
  alert('ok');
});

こうやって無名関数をセットすれば、いちいち変数を作らなくてもすみます。

読み込むときも

sym.getComposition().getStage().getVariable('myFunction')();

と最後に括弧をつけることで、即実行することができます。

関数をいっぱい使うなら

var stage = sym.getComposition().getStage();
stage.getVariable('myFunction')();

とエイリアスを作れば多少は…

…やっぱりメンドクサイw

クロージャ…?


実はAdobeが推奨しない方法でもグローバルっぽい関数は実現できます。
単にシンボルを包んでいる即時関数の一つ外側にコードを書けばいいだけです。
それだけですべてのシンボルから参照できます。

ただ、これはグローバルではなくクロージャによって保持された環境…だと思います。
うーん、あいまいなのはedge APIを調べようとしたら難解すぎてよくわからなかったんですw
edgeAction.jsは全体が即時関数で包まれているので、その中はすべてローカルな環境です。
中で何をしているかというと、グローバルなAdobeEdgeオブジェクトにメソッドを定義しているだけ…のはずです。
ということは一度実行されたらすべて消えてしまうはずなのに、中に書いた変数やオブジェクトは保持されたままでした。
ということは状況証拠的にクロージャによって保持されたローカルな環境…のはず。
試しに
var test = 1;
とシンボルの外側に書いて、シンボル内でwindow.testを表示させてみたらundefinedでした。
やっぱりグローバルな変数ではないようです。

だから、ローカルな環境だけどシンボルアクションからいつでも参照することが可能な環境、です。

ここに変数や関数を書けば、すべてのシンボルから参照することができますが、仕組みがわからないところに変更を加えるのは、いろいろ問題が起きる可能性があるので、大人しくsetVariableを使った方がいいかも…。

まとめ


一番確実で楽な方法は、一つだけグローバルオブジェクトを作って、プロパティやメソッドを定義することだと思います。
要はJSライブラリの手法ですね。
Edge Animateでは外部スクリプトのロードに対応しているので、簡単に実装できます。
これなら、グローバルへの影響を最小限に抑えつつ、処理の流れを簡単に把握することができますね。

ただし、Edge Animateからは外部スクリプトのエディットが出来ないので、他のエディターを用意する必要があります。
まあ、Edge Animateが使えるならDreamweaverが使えるので、それを使ってもいいですし、AdobeはオープンソースのHTML/CSS/JSエディターのbracketsも作っているので、これも結構使いやすいです。
iPadでいじりたいならTextasticがオススメですよ。







Related Posts Plugin for WordPress, Blogger...