BezierCurveEffect
FITCのときにこんなんあったよねって感覚で作った!
/**
* Copyright okoi ( http://wonderfl.net/user/okoi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xP84
*/
//
// FITCのHypeFrameworkの時にあったベジエ曲線ネタを
//
package
{
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.events.MouseEvent;
import flash.geom.Point;
import frocessing.color.ColorHSV;
[SWF(width = "465", height = "465")]
/**
* ...
* @author
*/
public class Main extends Sprite
{
private static const WIDTH:int = 465;
private static const HEIGHT:int = 465;
private var _canvas:BitmapData;
private var _sprite:Sprite;
private var _bezier:BezierObject;
private var _particlesPool:/*Particle*/Array;
private var _particles:/*Particle*/Array;
private static const PARTICLE_BUFFER:int = 1000;
private var _circleBMP:BitmapData;
private static const CIRCLE_R:int = 10;
private var _hsv:ColorHSV;
private var _step:int;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
graphics.beginFill(0);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
_canvas = new BitmapData( WIDTH, HEIGHT, true, 0 );
addChild( new Bitmap( _canvas ) );
_sprite = new Sprite();
addChild( _sprite );
_circleBMP = new BitmapData(CIRCLE_R*2, CIRCLE_R*2, true, 0);
var shape:Shape = new Shape();
shape.graphics.beginFill(0xFFFFFF);
shape.graphics.drawCircle(0, 0, CIRCLE_R);
shape.graphics.endFill();
_circleBMP.draw(shape, new Matrix(1, 0, 0, 1, CIRCLE_R, CIRCLE_R));
_hsv = new ColorHSV();
_step = 0;
InitBezierObject();
InitParticle();
addEventListener(Event.ENTER_FRAME, EnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, MouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, MouseUp);
}
private function InitBezierObject() : void
{
_bezier = new BezierObject(
new Point( WIDTH/4, HEIGHT / 2 ),
new Point( WIDTH/4, 50 ),
new Point( WIDTH / 4 * 3, HEIGHT / 2 ),
new Point( WIDTH / 4 * 3, 50 )
);
}
private function InitParticle() : void
{
_particles = new Array();
_particlesPool = new Array();
for ( var i:int = 0; i < PARTICLE_BUFFER; i++ )
{
_particlesPool.push( new Particle() );
}
}
private function MouseDown(e:MouseEvent) : void
{
_bezier.MouseDown();
}
private function MouseUp(e:MouseEvent) : void
{
_bezier.MouseUp();
}
private function EnterFrame(e:Event): void
{
_bezier.Update( stage.mouseX, stage.mouseY );
_canvas.lock();
_canvas.fillRect( _canvas.rect, 0x0 );
for ( var i:int = _particles.length - 1; i >= 0; i-- )
{
_particles[i].Update();
var mat:Matrix = new Matrix(_particles[i].sizerate, 0, 0, _particles[i].sizerate, _particles[i].x - CIRCLE_R, _particles[i].y - CIRCLE_R);
var color:uint = _particles[i].color;
var colorMat:ColorTransform = new ColorTransform(0, 0, 0, 0, (color >> 16) & 0xFF, (color >> 8) & 0xFF, (color >> 0) & 0xFF, 0xAA);
_canvas.draw( _circleBMP, mat, colorMat, "add");
if ( _particles[i].IsEnd() )
{
_particlesPool.push( _particles[i] );
_particles.splice( i, 1 );
}
}
_canvas.applyFilter( _canvas, _canvas.rect, new Point(), new BlurFilter() );
_canvas.unlock();
_sprite.graphics.clear();
_bezier.Draw(_sprite);
AddParticle();
_step++;
}
private function AddParticle() : void
{
var s:ControlPoint = _bezier.GetPoint( "start" );
var sc:ControlPoint = _bezier.GetPoint( "startctrl" );
var e:ControlPoint = _bezier.GetPoint( "end" );
var ec:ControlPoint = _bezier.GetPoint( "endctrl" );
//var rx1:Number;
//var ry1:Number;
for ( var i:int = 0; i < 5; i++ )
{
var p:Particle = _particlesPool.pop();
if ( p == null ) break;
var angle:Number = Math.random() * 360;
var pow:Number = Math.random() * sc.r;
var scrx:Number = Math.cos( angle * Math.PI / 180 ) * pow;
var scry:Number = Math.sin( angle * Math.PI / 180 ) * pow;
angle = Math.random() * 360;
pow = Math.random() * ec.r;
var ecrx:Number = Math.cos( angle * Math.PI / 180 ) * pow;
var ecry:Number = Math.sin( angle * Math.PI / 180 ) * pow;
_hsv.h = (_step / 5) % 360;
var color:uint = _hsv.value32;
p.Init( new Point(s.x, s.y), new Point(sc.x + scrx, sc.y + scry), new Point(e.x, e.y), new Point(ec.x + ecrx, ec.y + ecry), color );
_particles.push( p );
}
}
}
}
import flash.display.Shape;
import flash.geom.Point;
import flash.display.Sprite;
import flash.display.Graphics;
/**
* ベジエ曲線に沿って移動するパーティクル
*/
class Particle {
private var _start:Point;
private var _startCtrl:Point;
private var _end:Point;
private var _endCtrl:Point;
private var _step:Number; // 0~1
public function step():Number { return _step; }
private var _move:Number;
private var _x:Number;
public function get x():Number { return _x; }
private var _y:Number;
public function get y():Number { return _y; }
private var _disp:Boolean;
public function get disp():Boolean { return _disp; }
public function set disp(val:Boolean):void { _disp = val; }
private var _sizeRate:Number;
public function get sizerate():Number { return _sizeRate; }
private var _color:uint;
public function get color():uint { return _color; }
public function Particle() {
_disp = false;
}
public function Init(s:Point, sc:Point, e:Point, ec:Point, c:uint) : void
{
_start = s;
_startCtrl = sc;
_end = e;
_endCtrl = ec;
_move = 0.005;
_step = 0;
_sizeRate = Math.max( Math.random(), 0.5 );
_color = c;
}
public function Update() : void
{
_x = 0;
_y = 0;
var v:Number = (1 - _step) * (1 - _step) * (1 - _step);
_x += v * _start.x;
_y += v * _start.y;
v = 3 * _step * (1 - _step) * (1 - _step);
_x += v * _startCtrl.x;
_y += v * _startCtrl.y;
v = 3 * _step * _step * (1-_step);
_x += v * _endCtrl.x;
_y += v * _endCtrl.y;
v = _step * _step * _step;
_x += v * _end.x;
_y += v * _end.y;
_step += _move;
}
public function IsEnd() : Boolean
{
if ( _step < 1.0 ) return false;
return true;
}
}
/**
* ベジエ曲線に使う、点、制御点を管理するクラス
*/
class BezierObject {
private static const POINT_NAME:Array = [
"start", "startctrl", "endctrl", "end"
];
private static const POINT_SIZE:int = 5;
private static const POINT_DEF_R:int = 30;
private var _points:Object;
public function BezierObject(s:Point, sc:Point, e:Point, ec:Point) {
_points = new Object();
var point:ControlPoint = new ControlPoint(s.x, s.y, 0);
_points.start = point;
point = new ControlPoint(sc.x, sc.y, POINT_DEF_R);
_points.startctrl = point;
point = new ControlPoint(e.x, e.y, 0);
_points.end = point;
point = new ControlPoint(ec.x, ec.y, POINT_DEF_R);
_points.endctrl = point;
}
public function GetPoint( key:String ) : ControlPoint { return _points[key]; }
public function HitCheck(mx:Number, my:Number) : void
{
var len:Number = 0;
var point:ControlPoint;
var i:int;
for ( i = 0; i < 4; i++ )
{
point = _points[POINT_NAME[i]];
point.Out();
point.ROut();
}
for ( i = 0; i < 4; i++ )
{
point = _points[POINT_NAME[i]];
len = Math.sqrt((point.x - mx) * (point.x - mx) + (point.y - my) * (point.y - my));
if ( len < POINT_SIZE ){ point.Over(); return; }
// Control
if ( point.r != 0 && len >= point.r - 4 && len < point.r + 4 ){ point.ROver(); return; }
}
}
public function MouseDown() : void
{
for ( var i:int = 0; i < 4; i++ )
{
var point:ControlPoint = _points[POINT_NAME[i]];
if ( point.flg_over ){ point.flg_move = true; return; }
if (point.flg_r_over) { point.flg_r_move = true; return;}
}
}
public function MouseUp() : void
{
for ( var i:int = 0; i < 4; i++ )
{
var point:ControlPoint = _points[POINT_NAME[i]];
point.flg_move = false;
point.flg_r_move = false;
}
}
public function Update(mx:Number, my:Number) : void
{
HitCheck( mx, my );
var i:int;
for ( i = 0; i < 4; i++ )
{
var point:ControlPoint = _points[POINT_NAME[i]];
if ( point.flg_move )
{
point.x = mx;
point.y = my;
}
if ( point.flg_r_move )
{
var len:Number = Math.sqrt((point.x - mx) * (point.x - mx) + (point.y - my) * (point.y - my));
if ( len < 10 ) len = 10;
point.r = len;
}
}
}
public function Draw(sp:Sprite) : void
{
var i:int = 0;
var g:Graphics = sp.graphics;
var point:ControlPoint;
for ( i = 0; i < 4; i++ )
{
point = _points[POINT_NAME[i]];
if ( point.flg_move ) g.beginFill(0xFF0000);
else if ( point.flg_over == ControlPoint.OVER ) g.beginFill(0xFFFF00);
else g.beginFill(0x555555);
g.drawCircle( point.x, point.y, POINT_SIZE );
g.endFill();
}
for ( i = 0; i < 4; i++ )
{
point = _points[POINT_NAME[i]];
if ( point.r == 0 ) continue;
if ( point.flg_r_move ) g.lineStyle( 2, 0xff0000 );
else if ( point.flg_r_over ) g.lineStyle( 2, 0xFFFF00 );
else g.lineStyle( 2, 0x555555 );
g.drawCircle( point.x, point.y, point.r );
}
}
}
class ControlPoint {
public function ControlPoint(xx:Number = 0, yy:Number = 0, rr:Number = 0)
{
_x = xx;
_y = yy;
_r = rr;
_flg_over = OUT;
_flg_move = false;
_flg_r_over = false;
_flg_r_move = false;
}
private var _x:Number;
public function get x():Number { return _x; }
public function set x(val:Number):void { _x = val; }
private var _y:Number;
public function get y():Number { return _y; }
public function set y(val:Number):void { _y = val; }
private var _r:Number;
public function get r():Number { return _r; }
public function set r(val:Number):void { _r = val; }
public function get size():Number { return _r * 2; }
public function set size(val:Number):void { _r = val / 2; }
private var _flg_over:int;
public function get flg_over():int { return _flg_over; }
public function set flg_over(val:int):void { _flg_over = val; }
public static const OUT:int = 0;
public static const OVER:int = 1;
public function Over():void { _flg_over = OVER; }
public function Out():void { _flg_over = OUT; }
private var _flg_move:Boolean;
public function get flg_move():Boolean { return _flg_move; }
public function set flg_move(val:Boolean):void { _flg_move = val; }
private var _flg_r_over:Boolean;
public function get flg_r_over():Boolean { return _flg_r_over; }
public function ROver():void { _flg_r_over = true; }
public function ROut():void { _flg_r_over = false; }
private var _flg_r_move:Boolean;
public function get flg_r_move():Boolean { return _flg_r_move; }
public function set flg_r_move(val:Boolean):void { _flg_r_move = val; }
}