forked from: 【AS100本ノック】7回目:ローディング(バー)

by uwi forked from 【AS100本ノック】7回目:ローディング(バー) (diff: 174)
AS100本ノック
* 7回目のお題は「ローディング(バー)」
* あなたなりの「ローディング(バー)」を表現してください。
♥0 | Line 130 | Modified 2009-12-11 03:32:14 | MIT License
play

ActionScript3 source code

/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wyVk
 */

// forked from mex's 【AS100本ノック】7回目:ローディング(バー) 
/* 
 * AS100本ノック
 * 7回目のお題は「ローディング(バー)」
 * あなたなりの「ローディング(バー)」を表現してください。
 */
package {
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.utils.Timer;
    import flash.net.*;
    import flash.geom.*;
    import flash.filters.*;
    
    [SWF(backgroundColor="#000000")]
    public class Loading extends Sprite {
        private var _timer : Timer;
        private var _loader : Loader;
        private var _per : Number;
        
        private var _tf : TextField;
        
        public function Loading() {
            _tf = new TextField();
            _tf.textColor = 0xffffff;
            _tf.height = 465;
            addChild(_tf);
            
            init();
        }
        
        private function init() : void
        {
            var tfmt : TextFormat = new TextFormat("arial", 50, 0xffffff);
            
            var cf : ConvolutionFilter = new ConvolutionFilter(3, 3, [0, -1, 0, -1, 4, -1, 0, -1, 0]);
            
            var bmd : BitmapData = textToBitmapData("N", tfmt);
            bmd.applyFilter(bmd, bmd.rect, new Point(), cf);
            _tf.text = bordering(bmd).join('\n');
            // TODO 端点を適当な間隔で拾う
            // TODO 直線かスプラインでつなげる
            // TODO なんかやる
            
            addChild(new Bitmap(bmd));
            
            var date:Date = new Date();
            //一応ダミーの画像がキャッシュに残っても良いようにタイムスタンプ
            var stamp:String = addZero(date.getMonth() + 1, 2) + 
                               addZero(date.getDate(), 2) + 
                               addZero(date.getHours(), 2) + 
                               addZero(date.getMinutes(), 2) + 
                               String(date.getMilliseconds());
            _loader = new Loader();
            _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
            _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
//            _loader.load(new URLRequest("http://image.dev-mex.com/dummy.jpg?" + stamp));
            
            _timer = new Timer(100);
//            _timer.addEventListener(TimerEvent.TIMER, onTimer);
            _timer.start();
//            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function textToBitmapData(text : String, tfmt : TextFormat, scale : Number = 1) : BitmapData
        {
            var tf : TextField = new TextField();
            tf.defaultTextFormat = tfmt;
            tf.autoSize = "left";
            tf.text = text;
            
            var ret : BitmapData = new BitmapData(tf.width*scale, tf.height*scale, false, 0x000000);
            var mat : Matrix = new Matrix();
            mat.createBox(scale, scale);
            ret.draw(tf, mat);
            return ret;
        }
        
        private function onTimer(e : TimerEvent) : void
        {
            _tf.text = "" + _per;
        }
        
        private function onProgress(e : ProgressEvent) : void
        {
            _per = e.bytesLoaded / e.bytesTotal;
        }
        
        private function onComplete(e : Event) : void
        {
            _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
            _loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
            
            _timer.removeEventListener(TimerEvent.TIMER, onTimer);
            removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            
            // TODO last animation
        }
        
        private function onEnterFrame(e : Event) : void
        {
        }
        
        /**
         * 数字に、指定した桁数だけ0を足すメソッド。タイムスタンプ用。
         * 
         * @param num   0を足したい数字です。
         * @param digit 桁数です。
         * @return 計算結果の文字列です。
         */
        public function addZero( num:uint, digit:uint):String
        {
            var str:String = num.toString();
            var len:uint = str.length;
            var zeroNum:int = digit - len;
            if (zeroNum > 0)
            {
                var temp:String = "";
                for (var i:uint = 0; i < zeroNum;i++ )
                {
                    temp += "0";
                }
                str = temp + str;
            }
            return str;
        }
        

        /** 輪郭線抽出
         * @param s 2値化済み、ターゲット1-画素 背景0-画素
         * @return 輪郭線だけ抽出した画像
         */
        public function bordering(s:BitmapData):Array {
            var ret : Array = [];
            var b:BitmapData = new BitmapData(s.width, s.height, false, 0);
            for (var j:int = 1; j < s.height - 1; j++) {
                for (var i:int = 1; i < s.width - 1; i++) {
                    if (s.getPixel(i, j) != 0 && b.getPixel(i, j) == 0) {
                        if (s.getPixel(i - 1, j) == 0) { // 左側が0-画素
                            ret.push(chase4(i, j, 0, s, b)); // 外側境界の始点
                        } else if (s.getPixel(i + 1, j) == 0) { // 右側が0-画素
                            ret.push(chase4(i, j, 4, s, b)); // 内側境界の始点
                        }
                    }// なんかひとつながりにならない・・
                }
            }
            return ret;
        }
        
        private static const IS : Array = [0, 1, 1, 1, 0, -1, -1, -1];
        private static const JS : Array = [1, 1, 0, -1, -1, -1, 0, 1];
        private static const NEXT : Array = [7, 7, 1, 1, 3, 3, 5, 5];
        
        /** 輪郭線追跡
         * @param (i0, j0) 始点
         * @param code Freeman chain code (0~7)
         * @param s ソース画像
         * @param b 輪郭画像
         */
        private static function chase4(x:int, y:int, code:int, s:BitmapData, b:BitmapData):Array
        {
            var ret : Array = [[x, y]];
            s.setPixel(x, y, 0x000000);
            b.setPixel(x, y, 0xffffff);
            while(true){
                var i : uint;
                for(i = code;i < code + 8;i++){
                    if(s.getPixel(x + IS[i&7], y + JS[i&7])){
                        x += IS[i&7];
                        y += JS[i&7];
                        s.setPixel(x, y, 0x000000);
                        b.setPixel(x, y, 0xFFFFFF);
                        ret.push([x, y]);
                        break;
                    }
                }
                if(i == code + 8)break;
                code = NEXT[code];
            }
            return ret;
        }
    }
}