flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのDockアイコンをカスタマイズする方法の続きです。
Macで起動するAIRアプリのドックアイコンをアニメーションさせたいと思います。使用した画像はこちら。Flex SDK3.2に同梱されているものを加工しました。
AIRApp_icon128.png
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" creationComplete="onInit()"> <mx:Script> <![CDATA[ import mx.core.BitmapAsset; [Embed(source="assets/AIRApp_icon128.png")] private var icon128:Class; [Embed(source="assets/AIRApp_icon16.png")] private var icon16:Class; private var newIconBitmap:BitmapData; private var isAnimation:Boolean = false; private function onInit():void { if (NativeApplication.supportsDockIcon) { var bitmap128:BitmapData = (new icon128() as BitmapAsset).bitmapData; var dockIcon:DockIcon = NativeApplication.nativeApplication.icon as DockIcon; dockIcon.bitmaps = [bitmap128]; } else if (NativeApplication.supportsSystemTrayIcon) { var bitmap16:BitmapData = (new icon16() as BitmapAsset).bitmapData; var trayIcon:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon; trayIcon.bitmaps = [bitmap16]; } } private function onClick(event:MouseEvent):void { if (isAnimation) { this.removeEventListener(Event.ENTER_FRAME, onAnimation); btnAnimation.label = "Animation"; } else { if (NativeApplication.supportsDockIcon) { newIconBitmap = (new icon128() as BitmapAsset).bitmapData; } else if (NativeApplication.supportsSystemTrayIcon) { newIconBitmap = (new icon16() as BitmapAsset).bitmapData; } this.addEventListener(Event.ENTER_FRAME, onAnimation); btnAnimation.label = "Stop"; } isAnimation = !isAnimation; } private function onAnimation(event:Event):void { var iconBitmap:BitmapData; var matrix:Matrix; var rectangle:Rectangle; if (NativeApplication.supportsDockIcon) { var dockIcon:DockIcon = NativeApplication.nativeApplication.icon as DockIcon; iconBitmap = new BitmapData(128, 128, true, 0x00000000); matrix = new Matrix(1, 0, 0, 1, 0, -1); rectangle = new Rectangle(0, 0, 128, 128); iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle); matrix = new Matrix(1, 0, 0, 1, 0, 127); iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle); newIconBitmap = iconBitmap.clone(); dockIcon.bitmaps = [newIconBitmap]; } else if (NativeApplication.supportsSystemTrayIcon) { var trayIcon:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon; iconBitmap = new BitmapData(16, 16, true, 0x00000000); matrix = new Matrix(1, 0, 0, 1, 0, -1); rectangle = new Rectangle(0, 0, 16, 16); iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle); matrix = new Matrix(1, 0, 0, 1, 0, 15); iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle); newIconBitmap = iconBitmap.clone(); trayIcon.bitmaps = [newIconBitmap]; } } ]]> </mx:Script> <mx:Button label="Animation" id="btnAnimation" click="onClick(event)"/> </mx:WindowedApplication>
このアプリを起動するとDockにアイコンが表示されると同時に、以下の画面が開きます。
[Animation]ボタンをクリックすると、Dockアイコンが縦にくるくる動き始めます。まず最初のポイントです。[Animation]ボタンのクリックイベントでDockアイコンがアニメーションしているかどうかを判定して、アニメーションしていなければEvent.ENTER_FRAMEのイベントハンドラ(リスナー)を登録しています。46行目です。
this.addEventListener(Event.ENTER_FRAME, onAnimation);
アニメーションしていた場合は、Event.ENTER_FRAMEのイベントハンドラ(リスナー)を削除してアニメーションをストップします。36行目です。
this.removeEventListener(Event.ENTER_FRAME, onAnimation);
Flashに詳しい人ならわかると思うのですが、Event.ENTER_FRAMEとはムービークリップがステージに存在している間、フレームが更新されるたびに発生するイベントです。
[ブロードキャストイベント] 再生ヘッドが新しいフレームに入るときに送出されます。再生ヘッドが移動しない場合、またはフレームが 1 つしか存在しない場合、このイベントはフレームレートに合わせて継続的に送出されます。 このイベントはブロードキャストイベントであるため、このイベントに登録されているリスナーを持つすべての表示イベントによって送出されます。
DisplayObject – ActionScript 3.0 言語およびコンポーネントリファレンスより引用。
要するにAIRアプリの場合は起動中ずっと裏で発生していることになります。このイベントハンドラ(onAnimation)で何をしているかといいますと、まず61行目で、128pxで無色透明(ARGBの0x00000000)の正方形のBitmapオブジェクトを生成します。
iconBitmap = new BitmapData(128, 128, true, 0x00000000);
次に、AIRApp_icon128.pngの画像を格納したBitmapをMatrixクラスで操作していきます。Matrixクラスとは何かと言うと、Bitmap等のオブジェクトを平行移動、拡大 / 縮小、回転、傾斜したりすることが出来るクラスです。詳細はこちらをどうぞ。
Matrix – ActionScript 3.0 言語およびコンポーネントリファレンス
62行目になります。
matrix = new Matrix(1, 0, 0, 1, 0, -1);
では、AIRApp_icon128.pngを1pxずつ上に平行移動するためのMatrixオブジェクトを生成しています。
65行目では、128pxで無色透明の正方形のBitmap(iconBitmap)の上に、(newIconBitmapとmatrixで)1px上に平行移動させたBitmapを上書いています。
iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle);
これを繰り返すと、こんな感じになります。
[上にフェードアウトしていく感じの画像]
同じように
matrix = new Matrix(1, 0, 0, 1, 0, 127);
iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle);
66行目で、まずAIRApp_icon128.pngを127pxずつ下に平行移動するためのMatrixオブジェクトを生成しています。67行目では、65行目でdrawしたBitmapに更に、127px下に平行移動させたBitmapを上書いています。上書いているのは、上で1px平行移動させて枠からはみでたように見える部分です。
[下から昇ってくる感じの画像]
[上にフェードアウトしていく感じの画像]と[下から昇ってくる感じの画像]をガッチャンコさせてる感じですね。ガッチャンコを動かすと、、、
ちなみに、Windowsのタスクトレイアイコンの場合は、こんな感じです。
あたかもアニメーションしているように見えるんですねぇ~、これが。ソースコードは同じものを使用しています。ただ、どちらも1pxずつ移動させているのでDockアイコンのアニメーションはすごーく遅いです。が、フレームレートや移動量で調整可能です。これで一応、アニメーションも出来ました!
■関連記事へのリンク
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのDockアイコンをカスタマイズする方法(2009/2/3追記)
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンを回転させる方法 〜概要編〜(2009/2/3追記)
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンを回転させる方法 〜実装編〜(2009/2/3追記)
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンを縮小/拡大させる方法(2009/2/4追記)