反転とその変異によるマウス・インタラクティブ小品
/**
* 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();
}
}
}