javascriptからflashの関数を実行する
MTASC入門を兼ねてFlash / JavaScript Integration Kitのドキュメントに書いてあることそのままやってみます。actionscriptもmtascもよく知らないので基本的に手探りでやっています。動作確認はosx上のmtasc Ver.1.12, Firefox 1.5で行いました。
まずはmtasc側asソースを用意する。
flash2js.as
class Application { static var app:Application; var proxy:JavaScriptProxy; var log:Function; function initDebugger():Void { _root.createTextField( "tf", 1, 0, 0, 100, 20 ); _root.tf.border = true; _root.tf.text = ""; this.log = function( msg:String ) { _root.tf.text = msg; } } function Application() { var self:Object = this; proxy = new JavaScriptProxy( _root.lcId, this ); initDebugger(); log( _root.lcId ); } public static function main () { app = new Application(); } }
JavaScriptProxyインスタンス初期化時に渡している_root.lcIdがhtmlに配置されたflashオブジェクトidと対応する。複数flashオブジェクトと通信する場合は各オブジェクト分のproxyインスタンスが必要となるはず(未確認)。
initDebugger()関数内でテキストフィールドを生成し、そこへ出力するlog()関数をjavascript側から呼んでもらう予定。
NAME = flash2js SRC = $(NAME).as ASCOPT = -header 200:200:30 -swf $(NAME).swf ASC = mtasc $(NAME).swf : $(SRC) $(ASC) $(ASCOPT) -main $(SRC)
上記Makefile, flash2js.as, Flash / JavaScript Integration Kitに含まれるJavaScriptProxy.asとJavaScriptSerializer.asを同一ディレクトリに配置した状態でmakeするとflash2js.swfが生成される。
ただしmtascではJavaScriptProxy.asとJavaScriptSerializer.asをそのままコンパイル出来なかったので以下のような修正を行う。詳細はmtasc-ml過去ログ等を参照。
diff -u JavaScriptProxy.as.org JavaScriptProxy.as --- JavaScriptProxy.as.org 2005-06-13 15:28:08.000000000 +0900 +++ JavaScriptProxy.as 2006-05-07 01:59:39.000000000 +0900 @@ -61,9 +61,10 @@ */ //import the serializer class -import com.macromedia.javascript.JavaScriptSerializer; +//import com.macromedia.javascript.JavaScriptSerializer; -class com.macromedia.javascript.JavaScriptProxy +//class com.macromedia.javascript.JavaScriptProxy +class JavaScriptProxy { private var instance:Object; private var lcId:String; @@ -144,17 +145,26 @@ j.jsFunction("foo", [1, 2]); */ - public function __resolve(functionName:String):Function - { - var f:Function = function() - { - arguments.splice(0,0, functionName); - var f:Function = call; - f.apply(this, arguments); - }; - - return f; - } +// public function __resolve(functionName:String):Function +// { +// var f:Function = function() +// { +// arguments.splice(0,0, functionName); +// var f:Function = call; +// f.apply(this, arguments); +// }; +// +// return f; +// } + public function __resolve(functionName:String):Function { + var callRef:Function = call; + var f:Function = function(){ + arguments.splice(0,0, functionName); + var f:Function = callRef; + f.apply(this, arguments); + }; + return f; + } /* call
diff -u JavaScriptSerializer.as.org JavaScriptSerializer.as --- JavaScriptSerializer.as.org 2005-06-13 15:28:08.000000000 +0900 +++ JavaScriptSerializer.as 2006-05-07 02:05:22.000000000 +0900 @@ -60,7 +60,8 @@ */ -class com.macromedia.javascript.JavaScriptSerializer +//class com.macromedia.javascript.JavaScriptSerializer +class JavaScriptSerializer { /**************** Serialization Methods ****************/ @@ -285,7 +286,8 @@ } /* Deserializes a Boolean Value */ - public static function deserializeBoolean(s:String):String +// public static function deserializeBoolean(s:String):String + public static function deserializeBoolean(s:String):Boolean { return Boolean(s); } @@ -455,9 +457,13 @@ arr = o[varName]; } - for(var x:Number = 0; x < len; x++) +// for(var x:Number = 0; x < len; x++) +// { +// arr.push(parseNode(children[x], o)); +// } + for(var y:Number = 0; y < len; y++) { - arr.push(parseNode(children[x], o)); + arr.push(parseNode(children[y], o)); } return arr;
次にhtml,jsファイルを用意する。
Flash / JavaScript Integration Kit付属のJavaScriptFlashGateway.jsとJavaScriptFlashGateway.swfを./proxy以下に配置し、次のようなhtmlファイルを作成する。
<html> <head> <title>flash2js sample</title> <script type="text/javascript" src="./proxy/JavaScriptFlashGateway.js"></script> </head> <body> <script type="text/javascript"> <!-- var uid = new Date().getTime(); var flashProxy = new FlashProxy( uid, './proxy/JavaScriptFlashGateway.swf' ); //--> </script> <h1>flash2js</h1> <script type="text/javascript"> <!-- var tag = new FlashTag( 'flash2js.swf', 200, 200 ); tag.setFlashvars( 'lcId=' + uid ); tag.write( document ); //--> </script> <p><a href="javascript:flashProxy.call('log', 'logging from js!!!');">process flash function()</a></p> <p><a href="javascript:(function(){ alert( 'uid = ' + uid ); })();">check uid value</a></p> </body> </html>
htmlファイルを開くとswf内テキストフィールドにjavascriptで生成したuid値が入力されている状態となっている。html上の"process flash function()"をクリックするとjs内FlashProxyインスタンス経由でswf内テキストフィールドがjavascriptで指定した値になる。
mtasc, actionscript等については以下の内容を参考に上記コードを確認しました。
#スクリーンショットとかソース名はflash2jsになってるけどjs2flashのほうが適切ですね。