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

名刺を振り回してみる。

ITLのサイトで名刺を「RESET ALL CARDS」して
名刺をドラッグしたときの動きの再現方法の検討用。
Get Adobe Flash player
by nabe 28 Dec 2008
// forked from nabe's 名刺を投げてみる。
// forked from nabe's 名刺回転の検討の土台
// ITLのサイトで名刺を「RESET ALL CARDS」して
// 名刺をドラッグしたときの動きの再現方法の検討用。
// forked from nabe's ソースの雛形
package {

    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    [SWF(width="465", height="465", backgroundColor="0xAABBCC", frameRate="12")];  
    public class BaseClass extends Sprite {

        //画面サイズ。
        private var W_:uint;
        private var H_:uint;

        //状態の管理。
        private const statReleased:uint = 0;
        private const statBeginDrag:uint = 1;
        private const statDragging:uint = 2;
        private const statEndDrag:uint = 3;
        private var stat_:uint = statReleased;

        //現在の移動・回転の速度。
        private var vPos:Point = new Point(10, 5);
        private var vRot:Number = 5;

        //摩擦係数。運動神経がにぶい場合は値を大きくすると捕まえ易くなる。
        private const fPos:Number = 0.01;
        private const fRot:Number = 0.01;

        //名刺
        private var card_:Sprite;

        //マウスカーソル・重心の位置。
        private var currentCur:Point = new Point();
        private var lastCur:Point = new Point();
        private var lastGC:Point = new Point();

        public function BaseClass () {
        //コンストラクタ。ここから全体の処理が開始する。
        //1.初期化処理の呼び出しを仕込むに留める。
            addEventListener(Event.ADDED_TO_STAGE, init_);
        }

        private function init_ (event_:Event):void {
        //初期化処理。
        //1.用済みのリスナ登録を解除する。
            event_.target.removeEventListener(event_.type, arguments.callee);

        //2.画面サイズを取得する。            
            W_ = stage.stageWidth;
            H_ = stage.stageHeight;

        //3.実際の処理を書き足す。
            draw_();

        //4.イベント処理を登録する。
            updateCur();
            addEventListener(Event.ENTER_FRAME, update_);
            this.addEventListener(MouseEvent.MOUSE_DOWN, dragStart_);
            stage.addEventListener(MouseEvent.MOUSE_UP, dragEnd_);
        }

        private function draw_ ():void {
        //実際の表示内容を用意する。
        //後で表示位置をずらすので独立したShapeとする。
            card_ = new Sprite();
            var graphics_:Graphics = card_.graphics;
            graphics_.beginFill(0xCCCCFF);
            graphics_.drawRect(-40, -80, 80, 160);
            graphics_.endFill();
            addChild(card_);
        }

        private function dragStart_ (event_:MouseEvent):void {
        //ドラッグ開始時の処理。
            if (stat_ == statReleased) stat_ = statBeginDrag;
        }

        private function dragEnd_ (event_:MouseEvent):void {
        //ドラッグ終了時の処理。
            if (stat_ == statDragging) stat_ = statEndDrag;
        }

        private function update_ (event_:Event):void {
            updateCur();
            var dPos:Point = currentCur.subtract(lastCur);

            switch (stat_) {
            case statReleased:
            //慣性で移動中の処理。
                updatePos();
                updateRot();
                break;

            case statBeginDrag:
            //ドラッグ開始時の処理。
//マウスカーソルでつかむと、
//カーソル中心に回転し始める。

            //回転中心をカーソル位置にずらす。
                card_.x = -mouseX;
                card_.y = -mouseY;
                x = currentCur.x;
                y = currentCur.y;
                this.startDrag();
                stat_ = statDragging;
                break;

            case statDragging:
            //ドラッグ中の処理。
//マウスカーソルを振り回すと、
//回転中心はカーソル位置に合わせて移動する。
//回転速度が変化する。
                var dGC:Point = lastCur.subtract(lastGC);
                vRot -= (dPos.x * dGC.y - dPos.y * dGC.x) * 0.001; 
                //角加速度はドラッグ位置の重心からの変位とドラッグ方向の外積に比例するのか?
                updateRot();
                break;

            case statEndDrag:
            //ドラッグ終了時の処理。
//マウスカーソルを離すと、
//カーソル中心に回転していたものが移動し始める。
                vPos.x = dPos.x;
                vPos.y = dPos.y;

            //回転中心を重心位置に戻す。
                card_.x = 0;
                card_.y = 0;
                x = lastGC.x;
                y = lastGC.y;
                stopDrag();
                stat_ = statReleased;
                break;
            }
        }

        private function updateCur ():void {
        //マウスカーソル・重心の位置を更新する。
            lastCur.x = currentCur.x;
            lastCur.y = currentCur.y;
            currentCur.x = parent.mouseX;
            currentCur.y = parent.mouseY;

            var temp_:Point = new Point(card_.x, card_.y);
            temp_ = localToGlobal(temp_);
            temp_ = parent.globalToLocal(temp_);
            lastGC.x = temp_.x;
            lastGC.y = temp_.y;
        }

        private function updatePos ():void {
        //位置の更新。
        //新しい座標を求める。
            var newX:Number = x + vPos.x;
            var newY:Number = y + vPos.y;

        //座標を画面内に収める。
            if (Math.abs(newX) > W_) newX = newX % W_;
            if (Math.abs(newY) > W_) newY = newY % H_;

            if (newX < 0) newX += W_;
            if (newY < 0) newY += H_;

        //現在の位置を更新する。
            x = newX;
            y = newY;

        //摩擦を反映する。
            vPos.x *= (1 - fPos);
            vPos.y *= (1 - fPos);
        }
        private function updateRot ():void {
        //角度の更新。

        //現在の角度を更新する。
            rotation += vRot;

        //摩擦を反映する。
            vRot *= (1 - fRot);
        }
    }
}