LightSketch(psyark respection)
click / hold pressed
/**
* Copyright gupon ( http://wonderfl.net/user/gupon )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/eQiS
*/
/**
* click / hold pressed
*/
package{
import __AS3__.vec.Vector;
import caurina.transitions.Tweener;
import flash.display.GraphicsPathCommand;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.filters.GlowFilter;
[SWF(frameRate=60,backgroundColor="#000000")]
public class CurveToTest extends Sprite{
private var commandsAry:Vector.<Vector.<int>>;
private var dataAry:Vector.<Vector.<Number>>;
private var gcAry:Vector.<GraphicsController>;
private var gc:GraphicsController;
private var maxLineNum:int = 20;
private var segmentNum:int = 5;
private var ctrlArea:Number = 100;
private var flag:Boolean;
private var velocity:Number = 0;
public var _f:Number;
public function CurveToTest(){
if(stage)init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event = null):void{
removeEventListener( Event.ADDED_TO_STAGE, init);
gc = new GraphicsController(graphics);
commandsAry = new Vector.<Vector.<int>>();
dataAry = new Vector.<Vector.<Number>>();
gcAry = new Vector.<GraphicsController>();
generateLines();
stage.addEventListener(MouseEvent.MOUSE_DOWN, changeTween);
stage.addEventListener(MouseEvent.MOUSE_UP, changeTween);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function generateLines():void{
var pos:Point = new Point();
var ctrlPos:Point = new Point();
var prevCtrl:Point = new Point();
for(var i:int;i<maxLineNum;i++){
var s:Shape = new Shape();
var commands:Vector.<int> = new Vector.<int>();
var data:Vector.<Number> = new Vector.<Number>();
var gc:GraphicsController = new GraphicsController(s.graphics);
gc.thickness = Math.random()*4;
gc.color = 0xFFFFFF;
addChild(s);
var oRadius:Number = Math.max(stage.stageWidth,stage.stageHeight);
var radius:Number = oRadius;
var rad:Number=0;
for(var j:int=0;j<segmentNum;j++){
if(j==0){
rad = Math.random()*360 * Math.PI/180;
pos.x = Math.cos(rad) * oRadius + stage.stageWidth/2;
pos.y = Math.sin(rad) * oRadius + stage.stageHeight/2;
commands.push(GraphicsPathCommand.WIDE_MOVE_TO);
data.push(0,0,pos.x,pos.y);
} else {
rad = Math.random()*360 * Math.PI/180;
ctrlPos.x = Math.cos(rad)*radius + stage.stageWidth/2;
ctrlPos.y = Math.sin(rad)*radius + stage.stageHeight/2;
radius -= oRadius/segmentNum;
if(j==0){
prevCtrl.x = Math.random()*stage.stageWidth;
prevCtrl.y = Math.random()*stage.stageHeight;
}
//最後は中央に
if(j==segmentNum-1) pos = new Point(stage.stageWidth/2,stage.stageHeight/2);
else pos = Point.interpolate(ctrlPos,prevCtrl,0.5);
commands.push(GraphicsPathCommand.CURVE_TO);
data.push(prevCtrl.x, prevCtrl.y, pos.x, pos.y);
prevCtrl = ctrlPos.clone();
}
}
gcAry.push(gc);
commandsAry.push(commands);
dataAry.push(data);
}
}
private function enterFrameHandler(event:Event):void{
}
public function get f():Number{ return _f };
public function set f(value:Number):void{
_f = value;
drawLines();
}
private function drawLines():void{
for(var i:int=0;i<commandsAry.length;i++){
gcAry[i].drawLine(commandsAry[i],dataAry[i],_f);
}
}
private function changeTween(event:MouseEvent):void{
if( flag ){
filters = [new GlowFilter(0x59B2E6,1,20,20,3,3)];
Tweener.addTween(this, { f:1, time:4 });
flag = false;
} else {
filters = [new GlowFilter(0x59B2E6,0,0,0,0,0)];
Tweener.addTween(this, { f:0, time:4 });
flag = true;
}
}
}
}
import __AS3__.vec.Vector;
import flash.display.Graphics;
import flash.geom.Point;
class GraphicsController{
private var g:Graphics;
public var thickness:Number = 1;
public var color:Number = 0x3388DD;
public function GraphicsController(graphics:Graphics){
this.g = graphics;
}
/**
* 弧をdrawPathで描画するためのデータを返します
*/
public function objectArc(radius:Number, degree:Number, opposite:Boolean=false):Object{
//最終的に返す値。
var commands:Vector.<int> = new Vector.<int>();
var data:Vector.<Number> = new Vector.<Number>();
if( Math.abs(degree) > 360 ) degree %= 360;
var div:int = Math.ceil(degree/30);
var radians:Number = degree * Math.PI / 180;
var segment:Number = radians / div;
var _from:Number;
var _to:Number;
for(var i:int;i<div;i++){
//曲線の分割
if( opposite ){
_from = ( i == 0 ) ? radians : segment * ( div - i );
_to = ( div - i - 1 ) * segment;
} else {
_from = segment * i;
_to = (i == div-1) ? radians : segment * (i+1);
}
//初回ループ時に、最初の点に移動
if( i == 0 ){
var startPos:Point = new Point();
startPos.x = Math.cos(_from) * radius;
startPos.y = Math.sin(_from) * radius;
commands.push(2);
data.push(startPos.x, startPos.y);
}
//終着点
var endPos:Point = new Point();
endPos.x = Math.cos(_to) * radius;
endPos.y = Math.sin(_to) * radius;
//コントロールポイント
var controlPos:Point = new Point();
var basePos:Point = opposite ? endPos : startPos;
var rotate:Number = opposite ? _to : _from;
controlPos.y = radius * Math.tan(Math.abs(_to - _from)/2);
controlPos.x = basePos.x - Math.sin(rotate) * controlPos.y;
controlPos.y = basePos.y + Math.cos(rotate) * controlPos.y;
//Vectorに格納
commands.push(3);
data.push(controlPos.x, controlPos.y, endPos.x, endPos.y);
//次のループのために始点を移動
startPos.x = endPos.x;
startPos.y = endPos.y;
}
return { commands:commands, data:data };
}
/**
* 扇を描きます
*/
public function drawPie(degree:Number, radius:Number, innerRadius:Number = 0):void{
if(degree > 0){
g.clear();
g.beginFill(0x993300);
//g.lineStyle(2,0xFF0000);
var arc:Object = objectArc(radius,degree);
if( innerRadius == 0 ){
arc.commands.push(2);
arc.data.push(0,0);
g.drawPath(arc.commands, arc.data);
} else {
var oppositeArc:Object = objectArc(innerRadius,degree,true);
g.moveTo(radius, 0);
g.drawPath(arc.commands, arc.data);
oppositeArc.commands.push(2);
oppositeArc.data.push(radius, 0);
g.drawPath(oppositeArc.commands, oppositeArc.data);
}
}
}
/**
* パスのトリミングをします
*/
public function drawLine(commands:Vector.<int>, data:Vector.<Number>,f:Number = 0.5):void{
g.clear();
g.lineStyle(thickness,color);
var startPos:Point = new Point(data[2],data[3]);
var endPos:Point = new Point();
var trimPos:Point = new Point();
var controlPoint:Point = new Point();
var eachLength:Vector.<Number> = new Vector.<Number>();
var com:Vector.<int> = commands.concat();
var dat:Vector.<Number> = data.concat();
//全ての曲線の長さの合計をとっておく(それぞれの長さも)
//長さの算出は今のところ直線距離(改良予定)
var totalLength:Number = 0;
var i:int;
for(i=1;i<commands.length;i++){
endPos.x = data[i*4+2];
endPos.y = data[i*4+3];
eachLength.push(Math.sqrt(Math.pow(endPos.x-startPos.x,2)+Math.pow(endPos.y-startPos.y,2)));
totalLength += eachLength[i-1];
startPos.x = endPos.x;
startPos.y = endPos.y;
}
var length:Number = 0;
for(i=0;i<commands.length-1;i++){
if (length + eachLength[i] >= f*totalLength){
//その線分内での割合を算出
var _f:Number = (f*totalLength - length) / eachLength[i];
i++;
if(i != 0){
startPos.x = dat[(i-1)*4+2];
startPos.y = dat[(i-1)*4+3];
}
//コントロールポイント
controlPoint.x = data[i*4];
controlPoint.y = data[i*4+1];
endPos.x = data[i*4+2];
endPos.y = data[i*4+3];
//分割
var trimCtrl:Point = Point.interpolate(controlPoint,startPos,_f);
trimPos = Point.interpolate(Point.interpolate(endPos,controlPoint,_f),trimCtrl,_f);
com.splice(i, com.length-i);
dat.splice(i*4,dat.length-i*4);
com.push(3);
dat.push(trimCtrl.x,trimCtrl.y,trimPos.x,trimPos.y);
g.drawPath(com,dat);
i--;
break;
} else{
length += eachLength[i];
}
}
}
}