Beautifl - Flash Gallery

Thumbnail : Pies
Pies
gupon 2009-11-27 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

/*
 * 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;
	}
}