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

反転とその変異によるマウス・インタラクティブ小品

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

package {
    import com.bit101.components.RadioButton;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#ffffff")]
    /**
     * 反転とその変異によるマウス・インタラクティブ小品
     * @see http://aquioux.net/blog/uncategorized/first-html5-canvas/
     * @see http://jsdo.it/Aquioux/EgWP
     * @author YOSHIDA, Akio
     */
    public class Main extends Sprite {
        
        // 拡大率
        static private const SCALE:int = 100;

        // 円格納リスト(中心X座標、中心Y座標、半径の順で一次配列格納)
        private var circleList_:Vector.<Number>;

        // ビューア
        private var viewer_:Shape;
        
        // 円の色
        private var circleColor_:uint;

        // トゥイーン用変数
        // バネ係数
        static private const SPRING:Number   = 0.75;
        // 摩擦係数
        static private const FRICTION:Number = 0.95;
        // 前回の invertCenter[X/Y]
        private var prevInvertCenterX_:Number = 0.0;
        private var prevInvertCenterY_:Number = 0.0;
        // 速度
        private var vMouseX_:Number = 0.0;
        private var vMouseY_:Number = 0.0;
        
        // 同一モード内で動きを変えるための変数
        private var toggle_:int = 1;
        // 切替ボタン
        private var toggleButton_:Sprite;
        
        // ラジオボタン
        private var radioButton1_:RadioButton;    // 普通の反転
        private var radioButton2_:RadioButton;    // ヴァリエーション 1
        private var radioButton3_:RadioButton;    // ヴァリエーション 2


        /**
         * コンストラクタ
         */
        public function Main():void {
            setup();
            addEventListener(Event.ENTER_FRAME, update);
        }
        
        /**
         * セットアップ
         */
        private function setup():void {
            // 円データ生成
            circleList_ = new <Number>[];
            var len:int = 36;    // 表示する円の数
            var radian:Number = Math.PI * 2 / len;
            for (var i:int = 0; i < len; i++) {
                circleList_.push(Math.cos(radian * i), Math.sin(radian * i), 0.075);
            }
            circleList_.fixed = true;
            
            // 切替ボタン
            toggleButton_ = new Sprite();
            drawToggleButton();
            addChild(toggleButton_);
            toggleButton_.addEventListener(MouseEvent.CLICK, function():void {
                toggle_ *= -1;
                drawToggleButton();
            } );
            
            // ビューア生成
            viewer_ = new Shape();
            viewer_.x = stage.stageWidth  >> 1;
            viewer_.y = stage.stageHeight >> 1;
            addChild(viewer_);
            
            // 円の色決定
            circleColor_ = Math.random() < 0.5 ? 0x000000 : 0xffffff;
            
            // ラジオボタン
            radioButton1_ = new RadioButton(this, 5, 450, "invert", true);
            radioButton2_ = new RadioButton(this, radioButton1_.x + radioButton1_.width + 5, radioButton1_.y, "variation 1", false);
            radioButton3_ = new RadioButton(this, radioButton2_.x + radioButton2_.width + 5, radioButton2_.y, "variation 2", false);
            
            // 最初の描画
            draw(0, 0);
        }

        /**
         * アップデート
         * @param    event
         */
        private function update(event:Event):void {
            // 反転中心座標計算
            // マウスカーソル位置から現在の反転中心座標を求める
            var invertCenterX:Number = viewer_.mouseX / SCALE;
            var invertCenterY:Number = viewer_.mouseY / SCALE;
            // トゥイーン用速度計算
            vMouseX_ += (prevInvertCenterX_ - invertCenterX) * SPRING;
            vMouseY_ += (prevInvertCenterY_ - invertCenterY) * SPRING;
            vMouseX_ *= FRICTION;
            vMouseY_ *= FRICTION;
            // 現在の反転中心座標を退避
            prevInvertCenterX_ = invertCenterX;
            prevInvertCenterY_ = invertCenterY;
            // 反転中心座標の確定
            invertCenterX += vMouseX_;
            invertCenterY += vMouseY_;

            // 描画
            draw(invertCenterX, invertCenterY);
        }
        
        // 描画
        private function draw(invertCenterX:Number, invertCenterY:Number):void {
            var g:Graphics = viewer_.graphics;
            g.clear();
            g.beginFill(circleColor_);
            var len:int = circleList_.length / 3;
            for (var i:int = 0; i < len; i++) {
                // 円データ取り出し
                var localCenterX:Number = circleList_[i * 3 + 0];
                var localCenterY:Number = circleList_[i * 3 + 1];
                var localRadius:Number  = circleList_[i * 3 + 2];

                // 反転円中心と各円中心間の距離
                var distX:Number = localCenterX + invertCenterX;
                var distY:Number = localCenterY + invertCenterY;
                // 反転計算のための係数
                var s:Number = 1 / (distX * distX + distY * distY - localRadius * localRadius);
                //var s:Number = 1 / (distX * distX + distY * distY);
                // 反転後の各円の中心座標と半径
                var invertedX:Number;
                var invertedY:Number;
                if (radioButton1_.selected) {    // 反転
                    invertedX =  distX * s + (invertCenterX * toggle_);
                    invertedY = -distY * s + (invertCenterY * toggle_);
                }
                if (radioButton2_.selected) {    // ヴァリエーション 1
                    invertedX =  distX * s + (localCenterX * toggle_);
                    invertedY = -distY * s + (localCenterY * toggle_);
                }
                if (radioButton3_.selected) {    // ヴァリエーション 2
                    invertedX =  distX * s + (localCenterX * toggle_);
                    invertedY =  distY * s + (localCenterY * toggle_);
                }
                var invertedR:Number = localRadius * s;

                // 描画
                g.drawCircle(invertedX * SCALE, invertedY * SCALE, invertedR * SCALE);
            }
            g.endFill();
        }
        
        // 切替ボタン描画
        private function drawToggleButton():void {
            var color:uint = toggle_ == 1 ? 0x00ccff : 0xff4466;
            var g:Graphics = toggleButton_.graphics;
            g.beginFill(color);
            g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            g.endFill();
        }
    }
}