当我们在用一个带有渐变和边框的图片(形状最好是矩形或类似矩形)作为背景来适应各种大小宽高的时候,ScaleBitmap就很有用。虽然Bitmap有scale9Grid属性,可Bitmap自己不具备上述的使用功能。所以,有人就自己封装了ScaleBitmap。
假象一种环境。在你的应用里,会有很多提示。比如提示金钱不足,在线时间不够,权限不够等等。同样都是提示,而文字的长短不一,使得他们都的背景要适应文字的长短。这个时候,上边的ScaleBitmap就恰到好处了。于是,自己就封装了一个Tip类。用来做这样的提示。该提示可以一直展示,也可以选择显示一定的时间。但是,每次只能有一个显示出来。

作者提供的下载地址:http://www.bytearray.org/?p=118

效果如下:



code:

/**
 *
 *    ScaleBitmap
 *
 *     @version    1.1
 *     @author     Didier BRUN    -  http://www.bytearray.org
 *
 *     @version    1.2.1
 *     @author        Alexandre LEGOUT - http://blog.lalex.com
 *
 *     @version    1.2.2
 *     @author        Pleh
 *
 *     Project page : http://www.bytearray.org/?p=118
 *
 */

package org.bytearray.utils
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;

    public class ScaleBitmap extends Bitmap
    {

        protected var _originalBitmap:BitmapData;
        protected var _scale9Grid:Rectangle=null;

        function ScaleBitmap(bmpData:BitmapData=null, pixelSnapping:String="auto", smoothing:Boolean=false)
        {
            // super constructor
            super(bmpData, pixelSnapping, smoothing);

            // original bitmap
            _originalBitmap=bmpData.clone();
        }

        /**
         * setter bitmapData
         */
        
        override public function set bitmapData(bmpData:BitmapData):void
        {
            _originalBitmap=bmpData.clone();
            if (_scale9Grid != null)
            {
                if (!validGrid(_scale9Grid))
                {
                    _scale9Grid=null;
                }
                setSize(bmpData.width, bmpData.height);
            }
            else
            {
                assignBitmapData(_originalBitmap.clone());
            }
        }

        /**
         * setter width
         */
        override public function set width(w:Number):void
        {
            if (w != width)
            {
                setSize(w, height);
            }
        }

        /**
         * setter height
         */
        override public function set height(h:Number):void
        {
            if (h != height)
            {
                setSize(width, h);
            }
        }

        /**
         * set scale9Grid
         */
        override public function set scale9Grid(r:Rectangle):void
        {
            // Check if the given grid is different from the current one
            if ((_scale9Grid == null && r != null) || (_scale9Grid != null && !_scale9Grid.equals(r)))
            {
                if (r == null)
                {
                    // If deleting scalee9Grid, restore the original bitmap
                    // then resize it (streched) to the previously set dimensions
                    var currentWidth:Number=width;
                    var currentHeight:Number=height;
                    _scale9Grid=null;
                    assignBitmapData(_originalBitmap.clone());
                    setSize(currentWidth, currentHeight);
                }
                else
                {
                    if (!validGrid(r))
                    {
                        throw(new Error("#001 - The _scale9Grid does not match the original BitmapData"));
                        return;
                    }

                    _scale9Grid=r.clone();
                    resizeBitmap(width, height);
                    scaleX=1;
                    scaleY=1;
                }
            }
        }

        /**
         * assignBitmapData
         * Update the effective bitmapData
         */
        private function assignBitmapData(bmp:BitmapData):void
        {
            super.bitmapData.dispose();
            super.bitmapData=bmp;
        }

        private function validGrid(r:Rectangle):Boolean
        {
            return r.right <= _originalBitmap.width && r.bottom <= _originalBitmap.height;
        }

        /**
         * get scale9Grid
         */
        override public function get scale9Grid():Rectangle
        {
            return _scale9Grid;
        }


        /**
         * setSize
         */
        public function setSize(w:Number, h:Number):void
        {
            if (_scale9Grid == null)
            {
                super.width=w;
                super.height=h;
            }
            else
            {
                w=Math.max(w, _originalBitmap.width - _scale9Grid.width);
                h=Math.max(h, _originalBitmap.height - _scale9Grid.height);
                resizeBitmap(w, h);
            }
        }

        /**
         * get original bitmap
         */
        public function getOriginalBitmapData():BitmapData
        {
            return _originalBitmap;
        }

        // ------------------------------------------------
        //
        // ---o protected methods
        //
        // ------------------------------------------------

        /**
         * resize bitmap
         */
        protected function resizeBitmap(w:Number, h:Number):void
        {

            var bmpData:BitmapData=new BitmapData(w, h, true, 0x00000000);

            var rows:Array=[0, _scale9Grid.top, _scale9Grid.bottom, _originalBitmap.height];
            var cols:Array=[0, _scale9Grid.left, _scale9Grid.right, _originalBitmap.width];

            var dRows:Array=[0, _scale9Grid.top, h - (_originalBitmap.height - _scale9Grid.bottom), h];
            var dCols:Array=[0, _scale9Grid.left, w - (_originalBitmap.width - _scale9Grid.right), w];

            var origin:Rectangle;
            var draw:Rectangle;
            var mat:Matrix=new Matrix();


            for (var cx:int=0; cx < 3; cx++)
            {
                for (var cy:int=0; cy < 3; cy++)
                {
                    origin=new Rectangle(cols[cx], rows[cy], cols[cx + 1] - cols[cx], rows[cy + 1] - rows[cy]);
                    draw=new Rectangle(dCols[cx], dRows[cy], dCols[cx + 1] - dCols[cx], dRows[cy + 1] - dRows[cy]);
                    mat.identity();
                    mat.a=draw.width / origin.width;
                    mat.d=draw.height / origin.height;
                    mat.tx=draw.x - origin.x * mat.a;
                    mat.ty=draw.y - origin.y * mat.d;
                    bmpData.draw(_originalBitmap, mat, null, null, draw, smoothing);
                }
            }
            assignBitmapData(bmpData);
        }
    }
}

 

package com.vini123.tool
{
    import com.greensock.TweenMax;
    
    import flash.display.Bitmap;
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.TimerEvent;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.Timer;
    
    import asset.AssetManager;
    
    import org.bytearray.utils.ScaleBitmap;
    
    /**
     * 该tips仅仅一个实例,所以,在同一时间,只有一个弹出提示效果。 
     */    
    public class Tips extends Sprite
    {
        private static var _instance:Tips;
        private static var _isInside:Boolean = false;
        
        
        private var _bg:ScaleBitmap;
        private var _tipTxt:TextField;
        private var _tipTxtFormat:TextFormat;
        
        private var _font:String = "Microsoft yahei";
        private var _size:int = 28;
        private var _color:int = 0xffff00;
        private var _isBold:Boolean = true;
        
        private var _xGap:int = 8;
        private var _yGap:int = 20;
        
        private var _timer:Timer;
        private var _alphaChangeTime:Number = 0.6;
        
        public function Tips()
        {
            if(!_isInside)
            {
                throw new Error("这里是单例,禁止外部去实例化!");
            }
            init();
        }
        
        public static  function get instance():Tips
        {
            if(!_instance)
            {
                _isInside = true;
                _instance = new Tips();
                _isInside = false;
            }
            return _instance;
        }
        
        private function init():void
        {
            _tipTxtFormat = new TextFormat();
            _tipTxtFormat.font = _font;
            _tipTxtFormat.size = _size;
            _tipTxtFormat.color = _color;
            _tipTxtFormat.bold = _isBold;
            
            _tipTxt = new TextField();
            _tipTxt.mouseEnabled = false;
            _tipTxt.selectable = false;
            _tipTxt.multiline = false;
            _tipTxt.wordWrap = false;
            _tipTxt.autoSize = TextFieldAutoSize.CENTER;
            _tipTxt.defaultTextFormat = _tipTxtFormat;
            addChild(_tipTxt);
            
            _bg = new ScaleBitmap((new AssetManager.TipBg() as Bitmap).bitmapData);
            _bg.scale9Grid = new Rectangle(20,20,80,80);  //这里尽可能大将宽高设置大一点。这样使得你利用的空间更大。
            addChildAt(_bg , 0);
        }
        
        /**
         * 
         * @param tips String 传递的消息
         * @param posX int 整体相对于父对象的X坐标
         * @param posY int 整体相对于父对象的Y坐标
         * @param parent DisplayObject 父对象
         * @param showTime Number 展示的时间,单位是秒,可以是小数。如果是0,则表示一直显示。
         * 
         */            
        
        public function Tip(tips:String , posX:int , posY:int , parent:DisplayObject , showTime:Number = 0):void
        {
            _tipTxt.text = tips + " ";
            this.x = posX;
            this.y = posY;
            
            if(parent is Sprite)
                (parent as Sprite).addChild(this);
            
            if(parent is MovieClip)
                (parent as MovieClip).addChild(this);
            
            resizePos();
            resizeTime(showTime);
        }
        
        private function resizePos():void
        {
            _bg.setSize(_tipTxt.textWidth + _xGap * 4 , _tipTxt.textHeight + _yGap * 2); 
            _tipTxt.x = _xGap * 2 ;
            _tipTxt.y = _yGap ;
            
            this.alpha = 1;
            TweenMax.killAll();
            TweenMax.from(this , _alphaChangeTime ,{alpha:0});  //渐变出来
        }
        
        private function resizeTime(timeNum:Number):void
        {
            if(timeNum ==0)return;
            if(_timer)_timer.removeEventListener(TimerEvent.TIMER_COMPLETE , timerCompleteHandler);_timer =null;
            
            _timer = new Timer((timeNum + _alphaChangeTime *2) * 1000 ,1 );
            _timer.addEventListener(TimerEvent.TIMER_COMPLETE , timerCompleteHandler);
            _timer.start();
        }
        
        private function timerCompleteHandler(e:TimerEvent):void
        {
            _timer.removeEventListener(TimerEvent.TIMER_COMPLETE , timerCompleteHandler);
            _timer = null;
            TweenMax.to(this , _alphaChangeTime ,{alpha:0 , onComplete:function():void{
                if(this.parent)this.parent.removeChild(this);
            }})
        }
    }
}

 

package com.vini123.tool
{
    import flash.display.Shape;
    import flash.display.Sprite;
    
    public class NetStatus extends Sprite
    {
        private var _circle:Shape;
        private var _radius:int = 5;
        private var _gap:int = 2;
        private var _total:int = 5;
        
        private var _goodNetWorkColor:int = 0x00ff00; 
        private var _badNetWorkColor:int = 0xff0000; 
        
        public function NetStatus()
        {
            _circle = new  Shape();
            addChild(_circle);
            updataStatus(3);
        }
        
        private function updataStatus(num:int):void
        {
            _circle.graphics.clear();
            
            for(var i:int = 0 ; i < _total ; i++)
            {
                if(i < num)
                {
                    _circle.graphics.beginFill(_goodNetWorkColor , 1);
                }
                else
                {
                    _circle.graphics.beginFill(_badNetWorkColor , 1);
                }
                _circle.graphics.drawCircle((2 * _radius + _gap)*i , _radius , _radius);
                _circle.graphics.endFill();
                _circle.graphics.endFill();
            }
        }
    }
}

 

package asset
{
    public class AssetManager
    {
        [Embed(source = "tipBg.png")]
        public static const TipBg:Class;
    }
}

 

package com.vini123
{
    import com.vini123.tool.NetStatus;
    import com.vini123.tool.Tips;
    
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.utils.setTimeout;
    
    import asset.AssetManager;
    
    [SWF(width = "680" , height="450" , frameRate="30")]
    public class Test extends Sprite
    {
        public function Test()
        {
            var _this:Test = this;
            setTimeout(function():void{
                Tips.instance.Tip("我是一只小小小鸟,怎么飞也飞不高" , 95 , 50 , _this , 2);  //弹窗
            } , 2000);
        
            setTimeout(function():void{
                Tips.instance.Tip("用我三生烟火,换你一世迷离" , 130 , 50 , _this , 3);  //弹窗
            } , 7000);
            
            setTimeout(function():void{
                Tips.instance.Tip("海上生明月,天涯共此时。情人怨遥夜,竟夕起相思" , 0 , 50 , _this , 3);  //弹窗
            } , 12000);
            
            setTimeout(function():void{
                Tips.instance.Tip("www.vini123.com/ishow/" , 140 , 50 , _this , 0);  //弹窗
            } , 17000);
            
            var originalBitmap:Bitmap  =  new AssetManager.TipBg() as Bitmap;
            addChild(originalBitmap);
            
            originalBitmap.x = stage.stageWidth * 0.5 - originalBitmap.width * 0.5 ;
            originalBitmap.y = stage.stageHeight - originalBitmap.height - 50;
            
            var netStatus:NetStatus = new NetStatus();
            addChild(netStatus);
            netStatus.x = stage.stageWidth - netStatus.width - 5 ;
            netStatus.y = 5
        }
    }
}