先日、GIZMOコンポーネントのAS3版をリリースしました。AS3に対応したことで、Flash CS3に加えてFlex BuilderでもGIZMOのAPIへ一通りアクセス可能になったわけです。ということで、しばらく放置されていた連載エントリを締めてみたいと思います。
ただ、第4回まで執筆していたBetaNewsが不在のため、彼に変わって私タナカがお送りします。ここではFlex Builder 3 beta3を使って、GIZMOに昔っから同梱されている目ん玉グルグルをAS3に移植してみましょう。オリジナルはなんとAS1。時代の流れを感じます。
■GIZMOコンポーネントのダウンロード
さて、AS3版GIZMOコンポーネントは下記よりダウンロードできます。
[ 開発ツールダウンロード ]
コンポーネントのリファレンスはこちらです。
[ Gizmoコンポーネントリファレンス 2.1.1 (ActionScript 3.0) ]
コンポーネント(gizmo-as3.swc)をダウンロードしたら、Flex Builder 3のライブラリに追加しておきましょう。アプリケーションフォルダ内の sdks/3.0.0/frameworks/libs/ に入れておけばオッケーです。
■ガジェットの素材を用意
ガジェットで使うパーツはFlashで組み上げてしまうのが手っ取り早いです。Flex Builderではそれを外部SWFとしてロードします。スクリプトの処理はすべてFlex側で組み込むことにしたので、Flash素材には一切スクリプトを記述していません。今回は下図のようなeyes.swfを作りました。
※すべての作業はMacで行っていますが、残念ながら完成したガジェットは今のところWindowsでしか動作しません。
■パーツの読み込み
Flex Builder 3を起動して、Eyeballという名前の新規Flexプロジェクトを作成します。プロジェクトを作成すると、ユーザのドキュメントディレクトリ以下にあるFlex Builder 3フォルダ内にEyeballというプロジェクトフォルダが作成されます。その中にあるsrcフォルダへ、さきほどFlashで作ったeyes.swfを入れておきましょう。SWFLoaderコンポーネントを使ってコレをロードします。
また、ステージサイズが無意味に大きいとそれだけ描画負荷も上がるので、読み込む素材に合わせます。ついでに背景を透過させるためのスタイル設定も行えば、見た目の処理は完了です。
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="120" height="62">
<mx:Style>
Application
{
background-alpha:"0";
}
</mx:Style>
<mx:SWFLoader x="0" y="0" id="_loader" source="eyes.swf" complete="loadCompleteHandler()"/>
</mx:Application>
■グルグル回す
上のコードでは、SWFLoaderの読み込み完了時にloadCompleteHandler()を実行するよう設定してあります。そのタイミングで諸々の初期化を行っていきます。まずは、目玉が回るために必要な処理の設定です。
GIZMO APIでは、Desktop.mouseXとDesktop.mouseYでスクリーン上のマウス座標を取得できます。現在のガジェットの座標はGadget.xおよびGadget.yです。これらを利用してマウスと目玉(左右それぞれの黒目)の角度を計算し、回転させればよいわけです。で、回転させるタイミングですが、ユーザーがデスクトップ上でマウスを動かしたときでよいでしょう。これはDesktopEvent.MOUSE_MOVEイベントの通知を受け取ることで実現できます。
<mx:Script>
<![CDATA[
import jp.anthill.gizmo.*;
private var eyes_mc:MovieClip;private function loadCompleteHandler():void {
eyes_mc = _loader.content as MovieClip;
init();
}private function init():void {
eyes_mc.left_mc.rotate =
eyes_mc.right_mc.rotate = function():void {
var dx:int = Desktop.mouseX - Gadget.x - this.x;
var dy:int = Desktop.mouseY - Gadget.y - this.y;
var radian:Number = Math.atan2(dy, dx);
this.rotation = radian / (Math.PI / 180);
};
Desktop.addEventListener(DesktopEvent.MOUSE_MOVE, mouseMoveHandler);
}private function mouseMoveHandler(event:DesktopEvent):void {
eyes_mc.left_mc.rotate();
eyes_mc.right_mc.rotate();
}
]]>
</mx:Script>
■ガジェットの移動と終了
GIZMOはガジェットのドラッグ移動を自動的に処理してくれるので、基本的には開発者がその点を意識する必要はありません。しかし、今回のガジェットはドラッグしようとしても動いてくれません。なぜかと言うと、FlexのApplicationコンポーネントがマウスイベントを受け取るようになっているためです。GIZMOはマウスイベントを受け取るオブジェクト(主な想定はボタンやテキストフィールド)をドラッグ移動の対象から外すのです。もちろんこの設定を変えて、どこを掴んでもドラッグできるようにすることも可能ですが、ここでは次のようにGadget.startMove()メソッドで明示的に移動させます。マウスボタンを放せば自動的にドラッグが終わります。
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
private function mouseDownHandler(event:MouseEvent):void {
Gadget.startMove();
}
ガジェットの終了は右クリックメニューからも行えますが、スクリプトで終了する場合は、Gadget.close()メソッドを使います。クローズボタンで終了できるようにしましょう。
eyes_mc.close_btn.addEventListener(MouseEvent.CLICK, closeClickHandler);
private function closeClickHandler(event:MouseEvent):void {
Gadget.close();
}
■完成
これまでの処理をまとめたコードは次のようになります。クローズボタンはガジェットの上にマウスカーソルが乗った時だけ現れるよう、味付けも施しました。Gadget.getBounds()でガジェットの矩形領域が取得できるので、マウス座標と重なっているか判定しています。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="120" height="62"><mx:Style>
Application
{
background-alpha:"0";
}
</mx:Style><mx:SWFLoader x="0" y="0" id="_loader" source="eyes.swf" complete="loadCompleteHandler()"/>
<mx:Script>
<![CDATA[
import jp.anthill.gizmo.*;
private var eyes_mc:MovieClip;private function loadCompleteHandler():void {
eyes_mc = _loader.content as MovieClip;
init();
}private function init():void {
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
eyes_mc.left_mc.rotate =
eyes_mc.right_mc.rotate = function():void {
var dx:int = Desktop.mouseX - Gadget.x - this.x;
var dy:int = Desktop.mouseY - Gadget.y - this.y;
var radian:Number = Math.atan2(dy, dx);
this.rotation = radian / (Math.PI / 180);
};
eyes_mc.close_btn.visible = false;
eyes_mc.close_btn.addEventListener(MouseEvent.CLICK, closeClickHandler);
Desktop.addEventListener(DesktopEvent.MOUSE_MOVE, mouseMoveHandler);
}private function mouseDownHandler(event:MouseEvent):void {
Gadget.startMove();
}private function mouseMoveHandler(event:DesktopEvent):void {
eyes_mc.left_mc.rotate();
eyes_mc.right_mc.rotate();
var bounds:Rectangle = Gadget.getBounds();
eyes_mc.close_btn.visible = bounds.containsPoint(event.position);
}private function closeClickHandler(event:MouseEvent):void {
Gadget.close();
}
]]>
</mx:Script></mx:Application>
これでリリースビルドを書き出せば、ガジェットのSWFは完成です。後は、次のようなガジェット定義ファイルを用意して、ガジェットフォルダにまとめます。ガジェットフォルダ名は任意ですが、ここではEyeball_Flexにします。
<?xml version="1.0" encoding="utf-8" ?>
<gadget xmlns="http://gizmo.anthill.jp/gadget/2.0" version="1.0">
<content src="Eyeball.swf" />
<title>Eyeball Flex</title>
<author>タナカヤスヒロ</author>
<description>Flexで作った目玉です。</description>
<menu>
<close label="閉じる" />
</menu>
</gadget>
ガジェットフォルダが用意できたら、WindowsのDocuments and Settings\ユーザ名\Application Data\GIZMO2\deck\community\gadget\以下に置くとGIZMOで動かすことができます。