flash on 2009-11-12
/**
* Copyright gupon ( http://wonderfl.net/user/gupon )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/f8Mv
*/
package {
import caurina.transitions.Tweener;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(backgroundColor="#333333", frameRate="60")]
public class TopPage extends Sprite{
private var graphicsLib:GraphicsLib;
private var _degree:Number = 50;
public var innerRadius:Number = 0;
public var radius:Number = 300;
private var flag:Boolean;
private var plane:Shape;
public function TopPage(){
if( stage ) init();
else addEventListener( Event.ADDED_TO_STAGE, init);
}
private function init(event:Event=null):void{
removeEventListener(Event.ADDED_TO_STAGE, init);
addChild(new CurveToTest());
plane = new Shape();
plane.x = 300;
plane.y = 200;
addChild(plane);
graphicsLib = new GraphicsLib();
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
}
public function get degree():Number{ return _degree };
public function set degree(value:Number):void{
_degree = value;
GraphicsLib.drawPie(plane.graphics, _degree, radius, innerRadius);
}
private function onMouseDownHandler( event:MouseEvent ):void{
if(flag){
Tweener.addTween(this, { degree:0, radius:300, innerRadius:0, time:3, transition:"easeOutCubic"});
Tweener.addTween(this, { innerRadius:0, time:3, transition:"easeInOutCubic" });
Tweener.addTween(plane, { rotation:0, time:3, transition:"easeOutCubic" });
flag = false;
} else {
Tweener.addTween(this, { degree:360, radius:150, time:3, transition:"easeOutCubic"});
Tweener.addTween(this, { innerRadius:120, time:3, transition:"easeInOutCubic" });
Tweener.addTween(plane, { rotation:270, time:3, transition:"easeOutCubic" });
flag = true;
}
}
}
}
import __AS3__.vec.Vector;
import caurina.transitions.Tweener;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
class CurveToTest extends Sprite{
private var gLib:GraphicsLib;
private var commands:Vector.<int> = new Vector.<int>();
private var data:Vector.<Number> = new Vector.<Number>();
private var _f:Number;
private var flag:Boolean;
public function CurveToTest(){
commands.push(3);
data.push(0, 300, 300, 300 );
f = 0.3;
if(stage)init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event = null):void{
removeEventListener( Event.ADDED_TO_STAGE, init);
stage.addEventListener(MouseEvent.CLICK, changeTween);
}
private function changeTween(event:MouseEvent):void{
if( flag ){
Tweener.addTween(this, { f:1, time:3 });
flag = false;
} else {
Tweener.addTween(this, { f:0, time:3 });
flag = true;
}
}
public function set f(value:Number):void{
_f = value;
GraphicsLib.trimPath(graphics, commands, data, _f);
}
public function get f():Number{ return _f };
}
import __AS3__.vec.Vector;
import flash.display.Graphics;
import flash.geom.Point;
class GraphicsLib{
public function GraphicsLib(){
}
/**
* 弧をdrawPathで描画するためのデータを返します
*/
public static 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 static function drawPie(g:Graphics, degree:Number, radius:Number, innerRadius:Number = 0):void{
if(degree > 0){
g.clear();
g.beginFill(0xCC8833);
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 static function trimPath(g:Graphics, commands:Vector.<int>, data:Vector.<Number>,f:Number = 0.5):void{
g.clear();
var startPos:Point = new Point();
var endPos:Point = new Point();
var trimPos:Point = new Point();
var controlPoint:Point = new Point();
for(var i:int;i<commands.length;i++){
//各変数に代入
controlPoint.x = data[0];
controlPoint.y = data[1];
startPos.x = 0;
startPos.y = 0;
endPos.x = data[2];
endPos.y = data[3];
var trimCtrl:Point = Point.interpolate(controlPoint,startPos,f);
trimPos = Point.interpolate(Point.interpolate(endPos,controlPoint,f),trimCtrl,f);
g.lineStyle(3,0x3399FF);
g.curveTo(trimCtrl.x,trimCtrl.y,trimPos.x,trimPos.y);
}
}
}