[转] 鼠标缓动跟随

http://bbs.9ria.com/viewthread.php?tid=81628&extra=page%3D1%26amp%3Borderby%3Ddateline%26amp%3Bfilter%3D2592000


发个小小的鼠标缓动跟随效果,看了《Making Things Move》后将里面的鼠标跟随扩展了一下
EaseToMouse.as
package {
        import animation.trigonometry.ArrowByLoad;
        import flash.display.Sprite;
        import flash.events.Event;

        /**
         * @author Maliu
         */
        [SWF(frameRate = 30)]        //这里的元数据标签要Flex SDK才支持,Flash IDE不支持
        public class EaseToMouse extends Sprite
        {
                private var arrow:ArrowByLoad;        //鼠标跟随的元件,外部载入
                private var easing:Number = 0.5; //缓动值,决定跟随速度的快慢,可自己尝试修改该值以观察效果
                private var vx:Number = 0;        //x轴速度
                private var vy:Number = 0;        //y轴速度
                private var angle:Number;        //角度,由dy与dx得到
                private var dx:Number;        //目标与当前元件的x轴距离
                private var dy:Number;        //目标与当前元件的y轴距离
                
                private var arrowArray : Array;        //储存跟随对象的数组
                private const numArrow:Number = 10;        //跟随对象的数目
                private const scaleValue:Number = 0.86;        //基础缩放值
                
                public function EaseToMouse()
                {
                        init();
                }
                //初始化
                private function init():void
                {
                        arrowArray = new Array();
                        for(var i:int = 0; i<numArrow; i++)
                        {
                                arrow = new ArrowByLoad();
                                addChild(arrow);
                                arrowArray.push(arrow);
                        }
                        this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
                        arrow.addEventListener(Event.COMPLETE, setScale); //侦听加载事件的完成,解决异步引起的不能缩小元件的问题
                }
                private function onEnterFrame(e:Event):void
                {
                        for(var i:int = 0; i<numArrow; i++)
                        {
                                //因为数组里不包含鼠标的坐标,因此分开判断进行不同的传值
                                if(i > 0)
                                {
                                        calEvery(arrowArray[i-1].x, arrowArray[i-1].y, arrowArray[i]);
                                }
                                else
                                {
                                        calEvery(mouseX, mouseY, arrowArray[i]);
                                }
                        }
                }
                //计算传入currentArrow的rotation,需要传入dx和dy
                private function calRotation(currentArrow:ArrowByLoad, dx:Number, dy:Number):void
                {
                        angle = Math.atan2(dy, dx);
                        currentArrow.rotation = angle * 180/Math.PI;
                }
                //计算每个元件的缓动,传入不同的目标值和缓动对象
                private function calEvery(targetX:Number, targetY:Number, currentArrow:ArrowByLoad):void
                {
                        dx = targetX - currentArrow.x;
                        dy = targetY - currentArrow.y;
                        if(Math.abs(dx)<1 && Math.abs(dy)<1)
                        {
                                vx = 0;
                                vy = 0;
                                //currentArrow.x = targetX;
                                //currentArrow.y = targetY;
                        }
                        else
                        {
                                vx = dx * easing;
                                vy = dy * easing;
                                calRotation(currentArrow, dx, dy);
                                //currentArrow.x += vx;
                                //currentArrow.y += vy;
                        }
                        currentArrow.x += vx;
                        currentArrow.y += vy;
                }
                //给每个元件赋予不同的缩放值和透明度
                private function setScale(e:Event):void
                {
                        var n:Number = this.numChildren;
                        var tempScale:Number = 0;
                        var temp:ArrowByLoad;
                        for(var i:int = 0; i<n; i++)
                        {
                                temp = arrowArray[i];
                                tempScale = Math.pow(scaleValue, i);
                                temp.scaleX = tempScale;
                                temp.scaleY = tempScale;
                                temp.alpha = tempScale;
                        }
                }
        }
}


其中元件是外部加载的图像,以下是加载的代码
ArrowByLoad.as
package animation.trigonometry {
        import flash.display.Bitmap;
        import flash.display.Loader;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.net.URLRequest;

        /**
         * @author Maliu
         */
        public class ArrowByLoad extends Sprite
        {
                private var _imgURL:String = "arrow-alt-right-black.png";
                private var _bitmap:Bitmap;
                public function ArrowByLoad()
                {
                        loadImg();
                }
                private function loadImg():void
                {
                        var loader:Loader = new Loader();
                        var request:URLRequest = new URLRequest(_imgURL);
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
                        loader.load(request);
                }
                private function loaded(e:Event):void
                {
                        _bitmap = e.target.content as Bitmap;
                        _bitmap.smoothing = true; //将Bitmap属性smoothing设为true后消除锯齿,默认为false
                        this.addChild(_bitmap);
                        _bitmap.x = -_bitmap.width/2;
                        _bitmap.y = -_bitmap.height/2;

                        dispatchEvent(e); //加载完成后发送事件,用于外部侦听事件,解决异步问题
                }
        }
}


这里使用外部加载的图像,如果在EaseToMouse.as初始化后直接设定ArrowByLoad类对象的scale值和alpha值,会发现并不能成功改变ArrowByLoad类对象的大小和透明度,因为EaseToMouse.as代码的执行和ArrowByLoad.as加载外部图像的代码执行为异步的,因此要在EaseToMouse内对加载完成事件进行监听才能成功改变scale值和alpha值。
当然,不加载外部图像,直接调用库中元件或者用[Embed]标签嵌入外部图像就不必要在EaseToMouse类中对加载行为进行监听了。

你可能感兴趣的:(PHP,Flex,Flash,ide,bbs)