flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンを回転させる方法 〜実装編〜の続きです。今回はDockアイコンを縮小/拡大させるアニメーションです。画像の横幅を徐々に縮小していき、サイズが0になった時点で元となる画像を左右反転させ、徐々に拡大していきます。今回は縦幅は変更しません。
サンプルソースはこちら。
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" horizontalAlign="center" verticalAlign="middle" 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 isAnimation:Boolean = false; private var isDecrement:Boolean = false; private var isReverse:Boolean = false; private var counter:int = 0; private function onInit():void { var bitmap:BitmapData; if (NativeApplication.supportsDockIcon) { bitmap = (new icon128() as BitmapAsset).bitmapData; } else if (NativeApplication.supportsSystemTrayIcon) { bitmap = (new icon16() as BitmapAsset).bitmapData; } else { NativeApplication.nativeApplication.exit(); } setIcon(bitmap); } private function setIcon(bitmap:BitmapData):void { NativeApplication.nativeApplication.icon.bitmaps = [bitmap]; } private function onClick(event:MouseEvent):void { if (isAnimation) { this.removeEventListener(Event.ENTER_FRAME, onAnimation); btnAnimation.label = "Animation"; } else { this.addEventListener(Event.ENTER_FRAME, onAnimation); btnAnimation.label = "Stop"; } isAnimation = !isAnimation; } private function onAnimation(event:Event):void { var iconBitmap:BitmapData; var newIconBitmap:BitmapData; var rectangle:Rectangle; if (isDecrement) { counter--; } else { counter++; } if (NativeApplication.supportsDockIcon) { iconBitmap = new BitmapData(128, 128, true, 0x0000000); newIconBitmap = (new icon128() as BitmapAsset).bitmapData; rectangle = new Rectangle(0, 0, 128, 128); } else { iconBitmap = new BitmapData(16, 16, true, 0x0000000); newIconBitmap = (new icon16() as BitmapAsset).bitmapData; rectangle = new Rectangle(0, 0, 16, 16); } setIcon(scaleBitmap(iconBitmap, newIconBitmap, rectangle, counter, isReverse)); if (counter == newIconBitmap.width) { isDecrement = true; isReverse = !isReverse; } else if (counter == 0) { isDecrement = false; } } private function scaleBitmap( iconBitmap:BitmapData, newIconBitmap:BitmapData, rectangle:Rectangle, counter:int, isReverse:Boolean):BitmapData { if (isReverse) { var tempBitmap:BitmapData; var tempRectangle:Rectangle; if (NativeApplication.supportsDockIcon) { tempBitmap = new BitmapData(128, 128, true, 0x00000000); tempRectangle = new Rectangle(0, 0, 128, 128) } else if (NativeApplication.supportsSystemTrayIcon) { tempBitmap = new BitmapData(16, 16, true, 0x00000000); tempRectangle = new Rectangle(0, 0, 16, 16) } var tempMatrix:Matrix = new Matrix(); tempMatrix.scale(-1, 1); tempMatrix.translate(tempBitmap.width, 0); tempBitmap.draw(newIconBitmap, tempMatrix, null, null, tempRectangle); newIconBitmap = tempBitmap.clone(); } var matrix:Matrix = new Matrix(); var sx:Number = (newIconBitmap.width-counter)/newIconBitmap.width var sy:Number = 1; var tx:Number = newIconBitmap.width/2-(sx*newIconBitmap.width/2); var ty:Number = 0; matrix.scale(sx, sy); matrix.translate(tx, ty); iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle); return iconBitmap; } ]]> </mx:Script> <mx:Button label="Animation" id="btnAnimation" click="onClick(event)"/> </mx:WindowedApplication>
大枠は前回のサンプルソースと同様です。違うところは、縮小/拡大するサイズをenterFrameイベントでインクリメント/デクリメントするところと、画像を加工する関数、scaleBitmapの中身くらいです。enterFrameイベントハンドラのonAnimation関数の前半部分の
if (isDecrement) { counter--; } else { counter++; }
では、counter変数をインクリメント/デクリメントすることで、画像の横幅を徐々に変更していきます。isDecrementフラグは、縮小/拡大の状態を表していて、falseの時に縮小、trueの時に拡大します。
onAnimationの後半部分の
if (counter == newIconBitmap.width) { isDecrement = true; isReverse = !isReverse; } else if (counter == 0) { isDecrement = false; }
では、画像の横幅を徐々に縮小していった結果、サイズが0になった時点でもとの画像を左右反転させ、徐々に拡大していきます。画像の左右反転の状態を示しているのがisReverseフラグです。trueの時に左右反転します
scaleBitmap関数の中の以下の部分では
var matrix:Matrix = new Matrix(); var sx:Number = (newIconBitmap.width-counter)/newIconBitmap.width var sy:Number = 1; var tx:Number = newIconBitmap.width/2-(sx*newIconBitmap.width/2); var ty:Number = 0; matrix.scale(sx, sy); matrix.translate(tx, ty); iconBitmap.draw(newIconBitmap, matrix, null, null, rectangle);
画像を縮小/拡大する処理を実装しています。
var sx:Number = (newIconBitmap.width-counter)/newIconBitmap.width;
で、x軸方向の圧縮率を求めます。
var sy:Number = 1;
y軸方向は圧縮/拡大しませんので、圧縮率は1です。
var tx:Number = newIconBitmap.width/2-(sx*newIconBitmap.width/2); var ty:Number = 0;
では、圧縮/拡大することによって画像の中心点が移動されますので、元の位置にもどす平行移動距離を求めています。計算式は、flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンを回転させる方法 〜概要編〜の
tx=x-ax-cy
ty=y-bx-dy
より求められます。圧縮/拡大時の変換行列は
となりますので、
tx=64-sx*64-0*64=64-sx*64
となるわけです。
元となる画像を反転させている部分は、
if (isReverse) { var tempBitmap:BitmapData; var tempRectangle:Rectangle; if (NativeApplication.supportsDockIcon) { tempBitmap = new BitmapData(128, 128, true, 0x00000000); tempRectangle = new Rectangle(0, 0, 128, 128) } else if (NativeApplication.supportsSystemTrayIcon) { tempBitmap = new BitmapData(16, 16, true, 0x00000000); tempRectangle = new Rectangle(0, 0, 16, 16) } var tempMatrix:Matrix = new Matrix(); tempMatrix.scale(-1, 1); tempMatrix.translate(tempBitmap.width, 0); tempBitmap.draw(newIconBitmap, tempMatrix, null, null, tempRectangle); newIconBitmap = tempBitmap.clone(); }
の、
tempMatrix.scale(-1, 1); tempMatrix.translate(tempBitmap.width, 0);
です。
では、実行してみます。
見方によっては画像中心点のy軸を基準に回転しているようにも見えますね。
■関連記事へのリンク
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのDockアイコンをカスタマイズする方法
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンをアニメーションさせる方法
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンを回転させる方法 〜概要編〜
flashcast:フリーで働くITエンジニア集団のブログ: Macで動くAIRアプリのカスタマイズしたDockアイコンを回転させる方法 〜実装編〜