In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

MouseGesture

Get Adobe Flash player
by umhr 11 Aug 2011
    Embed
/**
 * Copyright umhr ( http://wonderfl.net/user/umhr )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/zcjY
 */

package  
{
    
    import flash.display.Sprite;
    import flash.events.Event;
    /**
     * ...
     * @author umhr
     */
    [SWF(width = 465, height = 465, backgroundColor = 0x000000, frameRate = 30)]
    public class WonderflMain extends Sprite 
    {
        public function WonderflMain() 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
            
        }
        
        private function init(e:Event = null):void 
        {
            var canvas:Sprite = new Sprite();
            canvas.graphics.beginFill(0xFFFFFF);
            canvas.graphics.drawRoundRect(40, 40, stage.stageWidth - 80, stage.stageHeight - 80, 16, 16);
            canvas.graphics.endFill();
            addChild(canvas);
            
            addChild(new Logger(0, 0, 200, 150, false));
            
            var gesture:MouseGesture = new MouseGesture(canvas);
            
            // tapとswipeの閾値.(Number)
            // gesture.distance = 3;
            // タッチパネルの場合、同じ座標でup/downするのは難しいので、許容範囲を作る。
            // このピクセル以下だとtap、以上だとswipeと検出される。
            
            
            // 前のtapとの差がこの時間(ミリ秒)以下であれば、マルチタップとして認識ます.(Number)
            // gesture.mulitiTapDelay = 700;
            
            
            // この値の分のmouseMoveを保持したのちswipeであるかの判定をします.(int)
            // interval = 3;
            // この値の回数を受け取ったあと、距離を測る。
            // swipeの検出には、interval/FPSの時間がかかることになる。
            
            
            // longTap(長押し)と判断されるまでの時間(ミリ秒)を設定します.(Number)
            // gesture.delay = 1000;
            
            gesture.addEventListener(MouseGestureEvent.TAP, gesture_tap);
            gesture.addEventListener(MouseGestureEvent.SWIPE, gesture_swipe);
            gesture.addEventListener(MouseGestureEvent.TOUCH, gesture_touch);
            gesture.addEventListener(MouseGestureEvent.LONG_PRESS, gesture_longPress);
            
        }
        
        private function gesture_longPress(e:MouseGestureEvent):void 
        {
            Logger.log(e.type, e.gestureTarget);
        }
        
        private function gesture_touch(e:MouseGestureEvent):void 
        {
            Logger.log(e.type, e.x, e.y, e.point);
        }
        
        private function gesture_swipe(e:MouseGestureEvent):void 
        {
            Logger.log(e.type,e.point);
        }
        
        private function gesture_tap(e:MouseGestureEvent):void 
        {
            Logger.log(e.type, e.tapCount);
        }
    }
    
}

    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.text.TextFormat;

    class Logger extends Sprite
    {
        private var _textField:TextField;
        private var _isTrace:Boolean;
        
        static private var _instance:Logger;
        public function Logger(x:Number = 0, y:Number = 0, width:int = 200, height:int = 150, isTrace:Boolean = false)
        {
            this.x = x;
            this.y = y;
            _isTrace = isTrace;
            _instance = this;
            
            init(width, height);
        }
        
        private function init(width:int, height:int):void
        {
            graphics.beginFill(0x333333, 0.8);
            graphics.drawRect(0, 0, width, height);
            graphics.endFill();
            mouseChildren = mouseEnabled = false;
            
            _textField = new TextField();
            _textField.multiline = true;
            _textField.width = width;
            _textField.height = height;
            _textField.defaultTextFormat = new TextFormat("_sans", 12, 0xFFFFFF);
            addChild(_textField);
        }
        
        /**
         * 出力内容を投げます。
         * @param    ... rest
         */
        static public function log(... rest):void
        {
            
            if (_instance._isTrace) {
                trace.apply(null, rest);
            }
            
            var text:String = rest.join(" ");
            
            if(_instance._textField.text == ""){
                _instance._textField.text = text;
            }else{
                _instance._textField.appendText("\n" + text);
            }
            var re:String = _instance._textField.text;
            var textList:Array = re.split("\r");
            while(_instance._textField.textHeight + 5 > _instance._textField.height){
                textList.shift();
                _instance._textField.text = textList.join("\n");
            }
            
        }
    }

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    /**
     * ...
     * @author umhr
     */
    class Core extends EventDispatcher
    {
        private var _target:Sprite;
        private var _timer:Timer;
        /**
         * longTap(長押し)と判断されるまでの時間(ミリ秒)を設定します.
         */
        public var delay:Number = 1000;
        private var _isStop:Boolean;
        public function Core(target:Sprite) {
            _target = target;
            if (_target.parent) {
                init();
            }
            _target.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            _target.addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
        }
        protected function addedToStageHandler(event:Event):void {
            if (_isStop) { return };
            init();
        }
        protected function init():void {
            _target.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            _target.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        }
        protected function removedFromStageHandler(event:Event):void {
            _target.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            _target.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            _target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            if(_timer){            
                _timer.reset();
                _timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComp);
            }
        }
        
        /**
         * mouseDownイベントが発生すると実行されます.
         */
        public var onMouseDown:Function = function(event:MouseEvent):void { };
        private function atMouseDown(event:MouseEvent):void {
            onMouseDown(event);
        }
        
        protected function mouseDownHandler(event:MouseEvent):void {
            if (_isStop) { return };
            atMouseDown(event);
            _target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            _target.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            if (this.hasEventListener(MouseGestureEvent.SWIPE)) {
                _target.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                _target.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            }
            if(this.hasEventListener(MouseGestureEvent.LONG_PRESS)){
                _timer = new Timer(delay, 1);
                _timer.delay = delay;
                _timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComp);
                _timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComp);
                _timer.start();
            }
        }
        protected function mouseUpHandler(event:MouseEvent):void {
            if (_isStop) { return };
            _target.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            _target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            if(_timer){
                _timer.reset();
                _timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComp);
            }
        }
        
        protected function mouseMoveHandler(event:MouseEvent):void {
            if (_isStop) { return };
            if (!event.buttonDown) {
                if(_timer){
                    _target.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                    _timer.reset();
                    _timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComp);
                }
            }
        }
        protected function onTimerComp(event:TimerEvent):void {
            if (_isStop) { return };
            _timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComp);
        }
        
        /**
         * 二度と使えないように破棄します.
         * 
         */
        public function dispose():void {
            removedFromStageHandler(null);
            _target.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            _target.removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
            _target = null;
        }
        
        /**
         * 一時停止します.
         * 
         */
        public function stop():void {
            _isStop = true;
            removedFromStageHandler(null);
        }
        
        /**
         * 一時停止したものを再開します.
         * stop()の後に使います。
         */
        public function play():void {
            _isStop = false;
            if (_target.parent) {
                init();
            }
        }
        
    }
    

    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    /**
     * マウスジェスチャーを検知するクラス.
     * 管理しているもの
     * ・イベントのジェスチャー化
     * ・swipe,tap,doubleTap,longPressが取れる
     * ・swipeとtapは排他関係にある。
     * (swipeとtapを同時に示すことは無い)
     * 
     * イベントの参考
     * http://developer.apple.com/jp/devcenter/ios/library/documentation/iPadProgrammingGuide.pdf
     * ...
     * @author umhr
     */
    class MouseGesture extends Core
    {
        private var _distanceListX:Array = [];
        private var _distanceListY:Array = [];
        private var _downTarget:Object;
        private var _currentTarget:Object;
        private var _currentTapTarget:Object;
        private var _isSwipe:Boolean;
        private var _isLongTap:Boolean;
        private var _currentTapTime:Number;
        private var _isStop:Boolean;
        private var _tapCount:int;
        private var _target:Sprite;
        
        public function MouseGesture(target:Sprite) {
            super(target);
            _target = target;
        }
        override protected function onTimerComp(event:TimerEvent):void {
            //swipが実行された後だと、longPressのイベント送出がなされない。
            //ただし、longPressの後にswipeが送出される可能性はある
            if (!_isSwipe && _downTarget == _currentTarget) {
                super.onTimerComp(event);
                this.dispatchEvent(new MouseGestureEvent(_target.mouseX, _target.mouseY, 0, _currentTarget, MouseGestureEvent.LONG_PRESS));
            }
        }
        
        override protected function mouseDownHandler(event:MouseEvent):void {
            super.mouseDownHandler(event);
            if (_isStop) { return };
            this.dispatchEvent(new MouseGestureEvent(_target.mouseX, _target.mouseY, 0, _currentTarget, MouseGestureEvent.TOUCH));
            _distanceListX = [];
            _distanceListY = [];
            _isSwipe = false;
            _downTarget = event.target;
            _currentTarget = event.target;
        }
        override protected function mouseUpHandler(event:MouseEvent):void {
            super.mouseUpHandler(event);
            if (_isStop) { return };
            //swipが実行された後だと、tapのイベント送出がなされない。
            if (!_isSwipe && _downTarget == event.target) {
                var tapTime:Number = new Date().getTime();
                if (_currentTapTime && tapTime-_currentTapTime < mulitiTapDelay && _currentTapTarget == event.target) {
                    _tapCount ++;
                }else {
                    _tapCount = 1;
                }
                this.dispatchEvent(new MouseGestureEvent(_target.mouseX, _target.mouseY, _tapCount,event.target, MouseGestureEvent.TAP));
                _currentTapTarget = event.target;
                _currentTapTime = tapTime;
            }else {
                _tapCount = 0;
            }
        }
        
        /**
         * tapとswipeの閾値.
         * タッチパネルの場合、同じ座標でup/downするのは難しいので、許容範囲を作る。
         * このピクセル以下だとtap、以上だとswipeと検出される。
         * 
         * @default 3;
         * */
        public function get distance():Number { return Math.sqrt(_distance) };
        public function set distance(value:Number):void {
            _distance = value * value;
        }
        /*
         * 3pixelの半径の場合、9になる。
         * これは、mouseMoveHandler内で距離を出すときにsqrtするよりも、
         * あらかじめ二乗しておいた方が計算コストが低いから
         * */
        private var _distance:Number = 9;
        
        /**
         * 前のtapとの差がこの時間(ミリ秒)以下であれば、マルチタップとして認識ます.
         * 
         * @default 700
         */
        public var mulitiTapDelay:Number = 700;
        
        /**
         * この値の分のmouseMoveを保持したのちswipeであるかの判定をします.
         * 
         * @default 3
         */
        public var interval:int = 3;
        override protected function mouseMoveHandler(event:MouseEvent):void {
            super.mouseMoveHandler(event);
            if (_isStop) { return };
            if (!event.buttonDown) { return; };
            _currentTarget = event.target;
            _distanceListX.push(_target.mouseX);
            _distanceListY.push(_target.mouseY);
            //既定の回数を受け取ったあと、距離を測る。
            if (_distanceListX.length > interval) {
                var dx:Number = 0;
                var dy:Number = 0;
                var n:int = _distanceListX.length - 1;
                for (var i:int = 0; i < n; i++) {
                    dx += _distanceListX[i + 1] - _distanceListX[i];
                    dy += _distanceListY[i + 1] - _distanceListY[i];
                }
                if (dx * dx + dy * dy > _distance) {
                    _isSwipe = true;
                    this.dispatchEvent(new MouseGestureEvent(dx, dy, 0, event.target, MouseGestureEvent.SWIPE));
                }
                _distanceListX = [];
                _distanceListY = [];
            }
        }
        
        /**
         * 二度と使えないように破棄します.
         * 
         */
        override public function dispose():void {
            super.dispose();
            _downTarget = null;
            _currentTarget = null;
            _currentTapTarget = null;
            _target = null;
        }
        
        /**
         * 一時停止します.
         * 
         */
        override public function stop():void {
            super.stop();
            _isStop = true;
            _tapCount = 0;
        }
        
        /**
         * 一時停止したものを再開します.
         * stop()の後に使います。
         */
        override public function play():void {
            super.play();
            _isStop = false;
        }
    }
    

    import flash.events.Event;
    import flash.geom.Point;
    
    class MouseGestureEvent extends Event {
        
        /**
         * swipeのイベント.
         * 
         * @return "swipe"
         */
        public static const SWIPE:String = "swipe";
        
        /**
         * tapのイベント.
         * 
         * @return "tap"
         */
        public static const TAP:String = "tap";
        
        /**
         *  longPressのイベント.
         * 
         * @return "longPress"
         */
        public static const LONG_PRESS:String = "longPress";
        
        /**
         * touchのイベント
         * 
         * @return "touch"
         */
        public static const TOUCH:String = "touch";
        
        private var _x:Number;
        private var _y:Number;
        private var _gestureTarget:Object;
        private var _tapCount:int;
        
        public function MouseGestureEvent(x:Number, y:Number, tapCount:int, target:Object, type:String, bubbles:Boolean = false, cancelable:Boolean = false):void {
            super(type, bubbles, cancelable);
            
            this._x = x;
            this._y = y;
            this._gestureTarget = target;
            this._tapCount = tapCount;
        }
        
        /**
         * tapの場合は発生したx座標、swipeの場合は変化ベクトルのx値.
         * 
         * 複数回tapの場合、直近のmauseUp時のmouseX
         * 
         * @return tapの場合は発生したx座標、swipeの場合は変化ベクトルのx値
         */
        public function get x():Number { return _x; };
        
        /**
         * tapの場合は発生したy座標、swipeの場合は変化ベクトルのy値.
         * 
         * 複数回tapの場合、直近のmauseUp時のmouseY
         * 
         * @return tapの場合は発生したy座標、swipeの場合は変化ベクトルのy値
         */
        public function get y():Number { return _y; };
        
        /**
         * tapの回数.
         * 
         * mulitiTapDelayの時間内に次のtapが行われると、この値が加算されます。
         * 
         * @return tapの回数
         */
        public function get tapCount():int { return _tapCount; };
        
        /**
         * ジェスチャーを設定したオブジェクト.
         * 
         * @return ジェスチャーを設定したオブジェクト
         */
        public function get gestureTarget():Object { return _gestureTarget; };
        
        /**
         * tapの場合は発生した座標、swipeの場合は変化ベクトル.
         * 
         * 複数回tapの場合、直近のmauseUp時の座標
         * 
         * @return tapの場合は発生した座標、swipeの場合は変化ベクトル
         */
        public function get point():Point { return new Point(_x, _y); };
    }