forked from: Kaleido Sketch
forked from Kaleido Sketch (diff: 69)
左右キーでの回転操作を追加。 ソースはよりスパゲテーに。
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);
}
}