3D text (1D rotation)

by Thy
...
@author Thi
♥0 | Line 192 | Modified 2010-05-16 03:24:18 | MIT License
play

ActionScript3 source code

/**
 * Copyright Thy ( http://wonderfl.net/user/Thy )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3Ko5
 */

package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	/**
	 * ...
	 * @author Thi
	 */
	public class Main extends Sprite 
	{
		
		// usadas pra formar o texto
		private var texto:String = "Thi"
		private var TF:TextField = new TextField()
		private var format:TextFormat = new TextFormat("Arial", 200)
		private var tw:Number, th:Number
		
		// usada pra armazenar o desenho do texto, ou da screen
		private var TDATA:BitmapData
		private var DATA:BitmapData
		private var screen:Bitmap
		
		// câmera
		private var cam:Cam = new Cam()
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// desenha o bitmap do texto
			TF.defaultTextFormat = format
			TF.autoSize = TextFieldAutoSize.LEFT
			TF.text = texto
			stage.addChild(TF)
			
			// copia o desenho desse texto
			tw = TF.width
			th = TF.height
			TDATA = new BitmapData(tw, th, false, 0xFFFFFF)
			TDATA.draw(TF)
			
			// lixo
			stage.removeChild(TF)
			format = null
			TF = null
			
			// inicia pontos
			initPart()
			
			// inicia variáveis da screen (a única coisa que é mostrada na tela)
			DATA = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0)
			screen = new Bitmap(DATA, "auto", true)
			RECT = DATA.rect
			stage.addChild(screen)
			
			// listeners
			stage.addEventListener(KeyboardEvent.KEY_DOWN, down)
			stage.addEventListener(Event.ENTER_FRAME, ef)
			
		}
		
		// temp
		private var i:uint, j:uint, part:Part, X:Number, Y:Number, Z:Number
		// variáveis para partículas
		private var num:uint = 2000
		private var parts:Vector.<Part> = new Vector.<Part>(num)
		// inicia pontos
		private function initPart():void
		{
			// cria a primeira partícula
			part = new Part()
			parts[0] = part
			while ( TDATA.getPixel( (X = Math.random()*tw), (Y = Math.random()*th) ) != 0 )
			{
			
			}
			part.x = X
			part.y = Y
			part.z = 1
			
			// agora cria as próximas partículas
			i = 0
			while (++i < num)
			{
				// cria partículas, e as variáveis necessárias
				part = new Part()
				parts[i] = part
				parts[i - 1].next = part
				part.prev = parts[i - 1]
				
				// faz as posições serem aleatórias,e também serem de acordo com o desenho do texto
				while ( TDATA.getPixel( (X = Math.random()*tw), (Y = Math.random()*th) ) != 0 )
				{
					
				}
				part.x = X
				part.y = Y 
				part.z = Math.random() * 50 + 50
			}
			
			// lixo
			part = null
			X = NaN
			Y = NaN
		}
		
		
		// função onEnterFrame
		private var loop:Number = 0, seno:Number
		private function ef (e:Event = null):void
		{
			andarCam()
			
			loop += .1
			seno = Math.sin(loop)
			
			DATA.lock()
			render()
			filtros()
			DATA.unlock()
		}
		
		private function andarCam():void
		{
			cam.vx *= .9
			cam.vz *= .9
			
			cam.a += (mouseX - 232.5) * .0001
			
			A = cam.a
			cam.z += Math.cos(A) * cam.vz
			cam.x += Math.sin(A) * cam.vz
			
			A += Math.PI*.5 // aumenta o ângulo em 90°
			cam.z += Math.cos(A) * cam.vx
			cam.x += Math.sin(A) * cam.vx
		}
		
		private var A:Number, R:Number
		private var perspectiva:Number = 300, focal:Number
		private function render():void
		{
			
			part = parts[0]
			// distância dos pontos
			X = part.x - cam.x
			Y = part.y - cam.y
			Z = part.z - cam.z
			// ângulo da câmera em relação ao ponto, em relação ao eixo Y
			A = Math.atan2(Z, X)
			// raio da distância do ponto com a câmera, sem contar a altura
			R = Math.sqrt(X * X + Z * Z) // pitágoras ( r² = x² + z² )
			// ajusta as posições X e Z, de acordo com os ângulos
			X = Math.cos (A + cam.a) * R
			Z = Math.sin (A + cam.a) * R
			// calcula a focal (varia de 0 à 1)
			focal = perspectiva / (perspectiva + Z)
			// renderiza ponto
			X *= focal
			Y *= focal
			DATA.setPixel(X + 235, Y, 0xFF0000)
			
			// renderiza o resto das partículas
			while ((part = part.next) != null)
			{
				X = part.x - cam.x
				Y = part.y - cam.y
				Z = part.z - cam.z
				// ângulo da câmera em relação ao ponto, em relação ao eixo Y
				A = Math.atan2(Z, X)
				// raio da distância do ponto com a câmera, sem contar a altura
				R = Math.sqrt(X * X + Z * Z) // pitágoras ( r² = x² + z² )
				// ajusta as posições X e Z, de acordo com os ângulos
				X = Math.cos (A + cam.a) * R
				Z = Math.sin (A + cam.a) * R
				// calcula a focal (varia de 0 à 1)
				focal = perspectiva / (perspectiva + Z)
				// renderiza ponto
				X *= focal
				Y *= focal
				
				if (focal > 0)
				{
					DATA.setPixel(X+235, Y, 0xFFFFFF)
				}
				
				
			}
		}
		
		private var RECT:Rectangle
		private var COL:ColorTransform =  new ColorTransform(.9,.9,.9)
		private function filtros():void
		{
			DATA.colorTransform(RECT, COL)
		}
		
		
		
		private var key:uint
		// função KeyDown
		private function down(e:KeyboardEvent):void
		{
			key = e.keyCode
			
			if (key == 37)
			{
				// esquerda
				cam.vx -= 1
				
			} else if (key == 39)
			{
				// direita
				cam.vx += 1
			}
			if (key == 38)
			{
				// cima
				cam.vz += 1
			} else if (key == 40)
			{
				// baixo
				cam.vz -= 1
			}
		}
		
		
		
	}
	
}



//package  
//{
	/**
	 * ...
	 * @author Thi
	 */
	/*public*/ class Cam
	{
		
		public var x:Number, y:Number, z:Number, a:Number, vx:Number, vy:Number, vz:Number
		
		public function Cam(x:Number = 0, y:Number = 0, z:Number = 0, a:Number = 0, vx:Number = 0, vy:Number = 0, vz:Number = 0) 
		{
			this.x = x
			this.y = y
			this.z = z
			this.a = a
			this.vx = vx
			this.vy = vy
			this.vz = vz
			
		}
		
	}

//}

//package  
//{
	/**
	 * ...
	 * @author Thi
	 */
	/*public*/ class Part
	{
		public var x:Number, y:Number, z:Number, vx:Number, vy:Number, vz:Number
		public var prev:Part, next:Part
		
		public function Part(x:Number = 0, y:Number = 0, z:Number = 0, vx:Number = 0, vy:Number = 0, vz:Number = 0) 
		{
			this.x = x
			this.y = y
			this.z = z
			this.vx = vx
			this.vy = vy
			this.vz = vz
		}
		
	}

//}