[etude] Native3D
/**
* Copyright sekiryou ( http://wonderfl.net/user/sekiryou )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5ayj
*/
package {
import flash.display.*;
import flash.geom.*;
import flash.text.*;
import flash.events.Event;
import flash.utils.ByteArray;
import flash.filters.BlurFilter;
[SWF(width = "465", height = "465", backgroundColor = "0x000000", frameRate = "30")]
public class etudeNative3D extends Sprite {
private const STAGE_WIDTH:uint = 465;
private const STAGE_HEIGHT:uint = 465;
private const STAGE_CENTER_X:Number = STAGE_WIDTH * 0.5;
private const STAGE_CENTER_Y:Number = STAGE_HEIGHT * 0.5;
private var _canvas:BitmapData;
private var _glow:BitmapData;
private var _rect:Rectangle;
private var _cTra:ColorTransform;
private var mapList:Array = [];
private var totalParticle:uint = 3600;
private var particles:Array = [];
private var mtx3D:Matrix3D = new Matrix3D();
private var projection:PerspectiveProjection;
private var projectionMatrix3D:Matrix3D;
public function etudeNative3D() {
init();
}
private function init():void {
addChild( new Bitmap( _canvas = new BitmapData ( STAGE_WIDTH, STAGE_HEIGHT, true, 0x00FFFFFF ) ) );
_glow = new BitmapData( STAGE_WIDTH/4, STAGE_HEIGHT/4, false, 0x0 );
var bm:Bitmap = addChild( new Bitmap( _glow, PixelSnapping.NEVER, true ) ) as Bitmap;
bm.scaleX = bm.scaleY = 4;
bm.blendMode = BlendMode.ADD;
_rect = new Rectangle( 0, 0, STAGE_WIDTH, STAGE_HEIGHT );
_cTra = new ColorTransform( 0.95, 0.95, 0.95, 1.0 );
projection = new PerspectiveProjection();
projection.fieldOfView = 90;
projectionMatrix3D = projection.toMatrix3D();
mapList = textToBit();
for ( var i:uint = 0; i < totalParticle; i++ ) {
var particle:Particle = new Particle();
particles.push( particle );
var tmpPoint:Point = purposeMaker()
particle.dx = tmpPoint.x;
particle.dy = tmpPoint.y;
}
addEventListener( Event.ENTER_FRAME, onEnterFrameHandler );
}
private function textToBit():Array {
var tmpList:Array = [];
var accuracy:Number = 2;
var threshold:uint = 0x00FFFFFF;
for ( var i:uint = 0; i < 11; i++ ) {
var txt:TextField = new TextField();
txt.x = 0;
txt.y = 0;
txt.width = 90;
txt.height = 90;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
var tf:TextFormat = new TextFormat();
tf.font = "Font Bold";
tf.size = 80;
tf.align = TextFormatAlign.CENTER;
txt.textColor = 0xFFFFFF;
txt.defaultTextFormat = tf;
if ( i < 10 ) {
txt.text = String( i );
} else {
txt.text = ":";
}
var tw:uint = txt.width / accuracy;
var th:uint = txt.height / accuracy;
var mapData:BitmapData = new BitmapData( tw, th, true, 0x00000000 );
var matrix:Matrix = new Matrix();
matrix.scale( 1 / accuracy, 1 / accuracy );
mapData.draw(txt, matrix);
var byteArray:ByteArray = mapData.getPixels( new Rectangle( 0, 0, mapData.width, mapData.height ) );
byteArray.position = 0;
tmpList[ i ] = [];
for (var n:uint = 0; n < tw * th; n++) {
var color:uint = byteArray.readInt();
if ( color > threshold ) {
var pos:uint = n;
var px:Number = ( pos % tw ) * accuracy + txt.x;
var py:Number = Math.floor(pos / tw) * accuracy + txt.y;
tmpList[ i ].push( { dx:px, dy:py, dz:0 } );
}
}
}
return tmpList;
}
private function purposeMaker():Point {
var destination:Point = new Point();
var totalType:uint = 8;
var rndtxt:int = int( Math.random() * totalType );
var nDate:Date = new Date();
var Hour:String = String(nDate.hours + 100);
Hour = Hour.substring( 1, 3)
var Minute:String = String(nDate.minutes + 100);
Minute = Minute.substring( 1, 3)
var Second:String = String(nDate.seconds + 100);
Second = Second.substring(1, 3)
var str:String = Hour + ":" + Minute + ":" + Second;
str = str.substring( rndtxt, rndtxt + 1 );
if( rndtxt == 2 || rndtxt == 5 ) {
var dispTxt:uint = 10;
} else {
dispTxt = int( str );
}
var rndpoint:int = int( Math.random() * mapList[ dispTxt ].length );
destination.x = mapList[ dispTxt ][ rndpoint ].dx + rndtxt * 50 - ( totalType * 50 * 0.5 );
destination.y = mapList[ dispTxt ][ rndpoint ].dy - 45;
return destination;
}
private function onEnterFrameHandler( eventObject:Event ):void {
var vertices3D:Vector.<Number> = new Vector.<Number>();
var projectedVerts:Vector.<Number> = new Vector.<Number>();
var uvts:Vector.<Number> = new Vector.<Number>();
var offsetZ:Number = 300;
for ( var i:uint = 0; i < totalParticle; i++ ) {
particles[ i ].update();
vertices3D.push( particles[ i ].px, particles[ i ].py, particles[ i ].pz );
}
mtx3D.identity();
mtx3D.appendRotation( -20, Vector3D.Y_AXIS);
mtx3D.appendRotation( 20, Vector3D.X_AXIS);
mtx3D.appendTranslation( 0, 0, offsetZ );
mtx3D.append( projectionMatrix3D );
bugfix( mtx3D );
Utils3D.projectVectors( mtx3D, vertices3D, projectedVerts, uvts );
var variation:Number = 0.04;
var ctx:Number = mouseX / 465;
var cty:Number = mouseY / 465;
if ( ctx > 0.95 ) {
ctx = 0.95;
} else if ( ctx < 0.05 ) {
ctx = 0.05;
}
if ( cty > 0.95 ) {
cty = 0.95;
} else if ( cty < 0.05 ) {
cty = 0.05;
}
if ( ctx > _cTra.redMultiplier ) {
_cTra.redMultiplier += variation;
} else {
_cTra.redMultiplier -= variation;
}
if ( cty > _cTra.blueMultiplier ) {
_cTra.blueMultiplier += variation;
} else {
_cTra.blueMultiplier -= variation;
}
_canvas.lock();
_canvas.applyFilter( _canvas, _rect, new Point(), new BlurFilter( 1.6, 1.6 ) );
_canvas.colorTransform( _rect, _cTra );
var pvLength:uint = projectedVerts.length * 0.5;
for ( var j:uint = 0; j < pvLength; j++ ) {
if ( particles[ j ].arrivalFlag ) {
particles[ j ].renew();
var tmpPoint:Point = purposeMaker();
particles[ j ].dx = tmpPoint.x;
particles[ j ].dy = tmpPoint.y;
}
if( uvts[ j * 3 + 2 ] > 0 ) {
_canvas.setPixel32( projectedVerts[ j * 2 ] + STAGE_CENTER_X, projectedVerts[ j * 2 + 1 ] + STAGE_CENTER_Y, 0xFF999999 );
}
}
_canvas.unlock();
_glow.fillRect( _glow.rect, 0x00000000 );
_glow.draw( _canvas, new Matrix( 0.25, 0, 0, 0.25 ) );
}
private function bugfix( matrix:Matrix3D ):void {
var m1:Matrix3D = new Matrix3D(Vector.<Number>( [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 ] ) );
var m2:Matrix3D = new Matrix3D(Vector.<Number>( [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ] ) );
m1.append( m2 );
if ( m1.rawData[15] == 20 ) {
var rawData:Vector.<Number> = matrix.rawData;
rawData[15] /= 20;
matrix.rawData = rawData;
}
}
}
}
class Particle {
public var px:Number;
public var py:Number;
public var pz:Number;
public var dx:Number = 0;
public var dy:Number = 0;
public var dz:Number = 0;
public var easingX:Number = Math.random() * 0.08 + 0.16;
public var easingY:Number = Math.random() * 0.08 + 0.16;
public var easingZ:Number = Math.random() * 0.08 + 0.16;
private const range:Number = 0.1;
public var distance:Number;
public var arrivalFlag:Boolean = false;
public function Particle() {
renew();
}
public function update():void {
px += ( dx - px ) * easingX;
py += ( dy - py ) * easingY;
pz += ( dz - pz ) * easingZ;
distance = Math.sqrt( ( dx - px ) * (dx - px ) + ( dy - py ) * ( dy - py ) + ( dz - pz ) * ( dz - pz ) );
if ( distance < range ) {
arrivalFlag = true;
}
}
public function renew():void {
px = Math.random() * 800 - 400;
py = dy;
pz = Math.random() * 4000 - 2000;
arrivalFlag = false;
}
}