forked from: Kaleido Sketch

by ug24k8 forked from Kaleido Sketch (diff: 69)
左右キーでの回転操作を追加。
ソースはよりスパゲテーに。
♥2 | Line 204 | Modified 2010-11-05 01:32:51 | MIT License
play

ActionScript3 source code

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

/*
  なんかきれいになるかも?とおもってやってみたけど思った以上にきれいにならなかった…

  カーソルキーでベースを回転できるように変更。
  左右で回転、上で停止。
   */

package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.ui.Keyboard;
    import flash.utils.Timer;
    import frocessing.core.*;
    import frocessing.color.*;
    import frocessing.geom.FMatrix2D;

    [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]

    public class KaleidoSketch extends Sprite {

        static private const MARK_SIZE:uint = 12;
        static private const MARK_SPEED:Number = 10;
        static private const MARK_MIN_SPEED:Number = 3;
        static private const BRUSH_MAX_SIZE:uint = 8;
        static private const BRUSH_MIN_SIZE:uint = 2;

        static private var center_:Point = new Point();
        static private const rot_unit_:Number = 2 * Math.PI / MARK_SIZE;

        private var marker_:Vector.<Mark> = new Vector.<Mark>(MARK_SIZE);
        private var select_mark_:Mark = null;
        private var last_select_mark_:Mark = null;
        private var canvas_:F5BitmapData2D;
        private var canvas_bmp_:Bitmap;
        private var colortrans_:ColorTransform;
        private var brush_size_:Number = BRUSH_MIN_SIZE;
        private var add_rotate_:Number = 0;
        private var base_:Sprite = new Sprite();

        // constructor

        public function KaleidoSketch() {
            var i:int;
            center_.x = stage.stageWidth / 2;
            center_.y = stage.stageHeight / 2;

            canvas_ = new F5BitmapData2D(
                            stage.stageWidth * 1.5,
                            stage.stageHeight * 1.5,
                            false, 0x000000);
            canvas_.colorMode("hsv", 255);
            canvas_.blendMode = BlendMode.ADD;
            colortrans_ = new ColorTransform(
                                0.9999999999,
                                0.9999999999,
                                0.9999999999);

            canvas_bmp_ = new Bitmap(canvas_.bitmapData, "auto", true);
            canvas_bmp_.filters = [new BlurFilter(6, 6)];
            base_.x = stage.stageWidth / 2;
            base_.y = stage.stageHeight / 2;
            canvas_bmp_.x = -canvas_.width / 2;
            canvas_bmp_.y = -canvas_.height / 2;
            base_.mouseEnabled = false;
            addChild(base_);
            base_.addChild(canvas_bmp_);

            // マーク作成
            for (i = 0; i < MARK_SIZE; ++i) {
                marker_[i] = new Mark(i, Math.ceil(i * 255 / MARK_SIZE));
                marker_[i].pos = Point.polar(25, rot_unit_ * i).add(center_);

                // 描画登録
                addChild(marker_[i]);
                marker_[i].addEventListener(MouseEvent.MOUSE_DOWN, markMouseDown);
            }

            stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUp);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, stageMouseDown);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keycheck);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        // private

        private function synchronize():void {
            var i:int;
            var geom_pos:Point = select_mark_.pos.subtract(center_);
            var geom_rot:Number = Math.atan2(geom_pos.y, geom_pos.x);
            var geom_len:Number = geom_pos.length;

            // 元の位置からの角度差分(ただし偶数マークは反転値)
            var axis_rot:Number = select_mark_.id * rot_unit_;
            geom_rot -= axis_rot;
            if (select_mark_.id % 2 == 0) geom_rot *= -1;

            // 適用
            var new_rot:Number;
            for (i = 0; i < MARK_SIZE; ++i) {
                new_rot = i * rot_unit_ + ((i % 2)? geom_rot: -geom_rot);
                marker_[i].pos = Point.polar(geom_len, new_rot).add(center_);
            }
        }
        
        
        private function keycheck(evt:KeyboardEvent):void {
            switch(evt.keyCode) {
            case Keyboard.LEFT :
                add_rotate_ -= .2;
                break;
            case Keyboard.RIGHT :
                add_rotate_ += .2;
                break;
            case Keyboard.UP :
                add_rotate_ = 0;
                break;
            }
        }
        
        private function markMouseDown(evt:MouseEvent):void {
            if (select_mark_) select_mark_.cancel();
            var target:Mark = evt.target as Mark;
            if (target) {
                target.select();
                select_mark_ = target;
                last_select_mark_ = target;
                setChildIndex(select_mark_, numChildren-1);
            }
        }
        
        private function stageMouseUp(evt:MouseEvent):void {
            if (select_mark_) select_mark_.cancel();
            select_mark_ = null;
        }

        private function stageMouseDown(evt:MouseEvent):void {
            trace(evt.target);
            trace(evt.currentTarget);
            if (evt.target == evt.currentTarget) {
                if (last_select_mark_) {
                    last_select_mark_.select();
                    select_mark_ = last_select_mark_;
                    select_mark_.pos = new Point(stage.mouseX, stage.mouseY);
                }
            }
        }

        private function onEnterFrame(evt:Event):void {
            var i:int;
            if (select_mark_) {
                var oldPos:Point = marker_[0].pos.clone();
                var pos:Point = select_mark_.pos;
                var target:Point = new Point(stage.mouseX, stage.mouseY);
                var move:Point = target.subtract(pos);
                var brush_size:Number = BRUSH_MIN_SIZE;

                if (move.length > MARK_MIN_SPEED) {
                    if (move.length > MARK_SPEED) {
                        move.normalize(MARK_SPEED);
                    }
                    brush_size += (BRUSH_MAX_SIZE - BRUSH_MIN_SIZE) / (MARK_SPEED - MARK_MIN_SPEED)
                                    * (move.length - MARK_MIN_SPEED);
                }
                select_mark_.pos = pos.add(move);

                synchronize();
                var grad_mat:Matrix = new Matrix();
                if (! marker_[0].pos.equals(oldPos)) {
                    brush_size_ = (brush_size - brush_size_) * 0.3 + brush_size_;

                    canvas_.bitmapData.colorTransform(canvas_.bitmapData.rect, colortrans_);

                    // 動いた!
                    canvas_.beginDraw();
                    canvas_.noStroke();
                    canvas_.fill(select_mark_.hue, 255, 255, 255);
                    for (i = 0; i < MARK_SIZE; ++i) {
                        var point:Point = canvas_bmp_.globalToLocal(marker_[i].pos);
                        canvas_.circle(
                            point.x,
                            point.y,
                            brush_size_);
                    }
                    canvas_.endDraw();
                }
            }
            
            base_.rotation += add_rotate_;
        }
    }
}

import flash.display.*;
import flash.events.*;
import flash.geom.*;
import frocessing.core.F5Graphics2D;


class Mark extends Sprite {
    static private const IN_SIZE:uint = 5;
    static private const OUT_SIZE:uint = 8;

    private var color_:uint;
    private var anime_frame_:uint;                    // アニメ用カウンタ
    private var id_:int;
    private var pos_:Point = new Point();
    private var fg_:F5Graphics2D;
    private var hue_:uint;

    // constructor

    public function Mark(id:int, hue:uint) {
        id_ = id;
        hue_ = hue;
        fg_ = new F5Graphics2D(graphics);
        fg_.colorMode("hsv", 255, 255, 255);
        drawCircle(OUT_SIZE);
    }


    // public

    public function get id():int { return id_; }

    public function get pos():Point { return pos_; }

    public function get hue():uint { return hue_; }

    public function set pos(pos:Point):void {
        pos_ = pos;
        x = pos_.x;
        y = pos_.y;
    }

    public function select():void {

        anime_frame_ = 0;
        addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    public function cancel():void {

        removeEventListener(Event.ENTER_FRAME, onEnterFrame);

        drawCircle(OUT_SIZE);
    }


    // private

    private function drawCircle(size:Number):void {
        graphics.clear();
        fg_.strokeWeight(1);

        // 内円
        fg_.noStroke();
        fg_.fill(hue_, 255, 255)
        fg_.circle(0, 0, IN_SIZE);

        // 外円
        fg_.stroke(hue_, 255, 255);
        fg_.noFill();
        fg_.circle(0, 0, size);
    }

    private function onEnterFrame(evt:Event):void {
        ++anime_frame_;
        var size:Number = IN_SIZE + (OUT_SIZE * 1.5 - IN_SIZE) * Math.sin(anime_frame_ * 0.1 % Math.PI);

        drawCircle(size);
    }
}