Pies
click or wait to change modes.
/**
* Copyright gupon ( http://wonderfl.net/user/gupon )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/9hLJ
*/
/*
* click or wait to change modes.
*/
package {
import __AS3__.vec.Vector;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Matrix;
import flash.geom.Point;
public class Pies extends Sprite {
private static const NUM_PIE:int = 8;
private static const WEIGHT:Number = 25;
private static const NUM_OCT:int = 4;
private var gc:GraphicsController;
private var canvas:Shape;
private var prog:Number = 0;
private var colors:Vector.<Number>;
private var points:Vector.<MovingPoint>;
private var bmp:Bitmap;
private var bmpData:BitmapData;
private var mapData:BitmapData;
private var noiseData:BitmapData;
private var dmf:DisplacementMapFilter;
private var mode:int = 0;
public function Pies(){
if ( stage ) init();
else addEventListener( Event.ADDED_TO_STAGE, init);
}
private function init( event:Event = null ):void{
removeEventListener( Event.ADDED_TO_STAGE, init );
drawBaseImage();
addEventListener( Event.ENTER_FRAME, enterFrame );
graphics.beginFill(0);
graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight);
buttonMode = true;
//bitmap
bmpData = new BitmapData(stage.stageWidth, stage.stageHeight, false );
bmp = new Bitmap(bmpData);
//displacement map
mapData = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0 );
noiseData = new BitmapData( stage.stageWidth/4, stage.stageHeight/4, false );
dmf = new DisplacementMapFilter( mapData, new Point(0,0), 1, 1, 200, 200, DisplacementMapFilterMode.WRAP );
addChild(bmp);
//generate moving points
points = new Vector.<MovingPoint>();
for( var i:int;i<NUM_OCT;i++ ){
var vx:Number = Math.random()*4 - 2;
var vy:Number = Math.random()*4 - 2;
var mp:MovingPoint = new MovingPoint( vx, vy );
trace(vx,vy);
points.push(mp);
}
stage.addEventListener( MouseEvent.CLICK, changeMode );
}
private function drawBaseImage():void{
canvas = new Shape();
gc = new GraphicsController( canvas.graphics );
colors = new Vector.<Number>();
for(var i:int=0;i<NUM_PIE;i++){
var h:Number = Math.random()*30;
colors.push( gc.HSVtoRGB( h, .9, .8 ));
}
}
private function enterFrame( event:Event ):void{
prog++;
if( prog%90 == 0 ) changeMode();
var growth:Number = Math.sin(prog%360*Math.PI/180*4)*.4 + .6;
//update pies
gc.clear();
for(var i:int=2;i<=NUM_PIE+1;i++){
var h:Number = Math.random()*360;
gc.beginFill(colors[i-2]);
gc.drawPie( i * WEIGHT-2, (i-1)*WEIGHT, (i+1)*30*growth, i*20*growth );
}
//matrix
var m:Matrix = new Matrix();
m.translate( stage.stageWidth/2, stage.stageHeight/2 );
//moving points to points
var ary:Array = [];
for each( var p:MovingPoint in points ) ary.push( new Point( p.x, p.y ));
//noise
noiseData.perlinNoise( noiseData.rect.width, noiseData.rect.height, NUM_OCT, 0, false, true, 7, true, ary );
mapData.draw( noiseData, new Matrix( 4, 0, 0, 4 ));
//final draw
if( mode != 2 ) bmpData.fillRect( bmpData.rect, 0x0 );
bmpData.draw( canvas, m, null, BlendMode.ADD, null, false );
if( mode != 0 ) bmpData.applyFilter( bmpData, bmpData.rect, new Point(0, 0), dmf );
}
private function changeMode( event:MouseEvent=null ):void{
mode++;
mode%=3;
}
}
}
import __AS3__.vec.Vector;
import flash.display.Graphics;
import flash.display.GraphicsPathCommand;
import flash.geom.Point;
class GraphicsController {
private var g:Graphics;
private var color:Number;
private var _degree:Number;
private var _innerRadius:Number;
private var _radius:Number;
private var commands:Vector.<int>;
private var data:Vector.<Number>;
private var _f:Number;
private var _f0:Number;
public function GraphicsController(graphics:Graphics){
this.g = graphics;
}
public function beginFill(color:uint):void{
g.beginFill(color);
}
public function clear():void{
g.clear();
}
/**
* 弧をdrawPathで描画するためのデータを返します
*/
public function objectArc(radius:Number, degree:Number, offsetDegree:Number=0, 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 offsetRadians:Number = offsetDegree * 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);
}
_from += offsetRadians;
_to += offsetRadians;
//初回ループ時に、最初の点に移動
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(radius:Number, innerRadius:Number=0, degree:Number = 60, offsetDegree:Number=0):void{
if(degree > 0){
var arc:Object = objectArc(radius, degree, offsetDegree);
if( innerRadius == 0 ){
arc.commands.push(GraphicsPathCommand.LINE_TO);
arc.data.push(0,0);
g.drawPath(arc.commands, arc.data);
} else {
var oppositeArc:Object = objectArc(innerRadius, degree, offsetDegree, true);
var offsetRadians:Number = offsetDegree * Math.PI / 180;
var x0:Number = Math.cos( offsetRadians ) * innerRadius;
var y0:Number = Math.sin( offsetRadians ) * innerRadius;
g.moveTo( x0, y0);
g.drawPath(arc.commands, arc.data);
g.drawPath(oppositeArc.commands, oppositeArc.data);
}
}
}
/**
* HSVをRGBに変換
*/
public function HSVtoRGB( h:Number, s:Number, v:Number ):uint{
var r:Number, g:Number, b:Number;
if( s != 0 ){
h %= 360;
var hi:uint = h / 60 % 6;
var f:Number = h / 60 - hi;
var p:Number = v * ( 1 - s );
var q:Number = v * ( 1 - f * s );
var t:Number = v * ( 1 - ( 1 - f ) * s );
switch( hi ){
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
}
} else r = g = b = v;
return ( 0xFF * r << 16 ) + ( 0xFF * g << 8 ) + ( 0xFF * b );
}
}
import flash.display.Sprite;
import flash.events.Event;
class MovingPoint extends Sprite{
public var vx:Number;
public var vy:Number;
public function MovingPoint( vx:Number, vy:Number ){
this.vx = vx;
this.vy = vy;
addEventListener( Event.ENTER_FRAME, enterFrame );
}
private function enterFrame( event:Event ):void{
x += vx;
y += vy;
}
}