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追記)






