package
{
import away3d.cameras.Camera3D;
import away3d.containers.Scene3D;
import away3d.containers.View3D;
import away3d.core.clip.RectangleClipping;
import away3d.core.math.Number3D;
import away3d.geom.AlignToPath;
import away3d.materials.ColorMaterial;
import away3d.materials.WireframeMaterial;
import away3d.primitives.Plane;
import away3d.primitives.TextField3D;
import com.adobe.viewsource.ViewSource;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.text.TextField;
import flash.text.TextFormat;
import wumedia.vector.VectorText;
SWF'#000000', frameRate='60')]
public class Main extends Sprite
{
Embed"assets/assets.swf", symbol="AwayLogo")]
private var LogoAsset:Class;
private var _scene:Scene3D;
private var _view:View3D;
private var _camera:Camera3D;
private var _width3d:Number;
private var _height3d:Number;
private var _loader:URLLoader;
private var _center:Number3D = new Number3D();
private var _interactiveSegment:InteractiveSegment;
private var _textfield:TextField3D;
private var _aligner:AlignToPath;
private var _pathLength:Number;
private var _xOffset:Number = 0;
private var _dir:int = 1;
private var _speed:Number = 5;
private var _textWidth:Number;
/**
* Constructor.
*/
public function Main()
{
ViewSource.addMenuItem(this, "srcview/index.html");
initStage();
loadFonts();
}
/**
* Init the away3d logo.
*/
private function initLogoAndHelp():void
{
var logo:Sprite = new LogoAsset();
logo.y = stage.stageHeight;
addChild(logo);
logo.addEventListener(MouseEvent.MOUSE_DOWN, logoMouseDownHandler);
var help:TextField = new TextField();
help.text = "*Drag the red nodes to edit the path.";
help.textColor = 0xFFFFFF;
help.width = 1000;
help.selectable = false;
var format:TextFormat = help.getTextFormat();
format.font = "Verdana";
format.size = 10;
help.setTextFormat(format);
addChild(help);
}
/**
* Logo on click.
*/
private function logoMouseDownHandler(evt:MouseEvent):void
{
navigateToURL(new URLRequest("http://www.away3d.com"), "_blank");
}
/**
* Init the stage settings.
*/
private function initStage():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
_width3d = stage.stageWidth;
_height3d = stage.stageHeight;
}
/**
* Load the assets swf to extract the fonts vector data.
* NOTE: Could be embedded also, just wanted to demonstrate another way to
* get vector stuff into 3d.
*/
private function loadFonts():void
{
_loader = new URLLoader();
_loader.dataFormat = URLLoaderDataFormat.BINARY;
_loader.addEventListener(Event.COMPLETE, onFontsLoadedHandler);
_loader.load(new URLRequest("assets/assets.swf"));
}
/**
* Continue initialization when fonts are ready.
*/
private function onFontsLoadedHandler(evt:Event):void
{
initFonts();
init3d();
init3dObjects();
initLogoAndHelp();
this.addEventListener(Event.ENTER_FRAME, render3d);
}
/**
* Use the swf binary data to extract the fonts.
* Wumedia's package at work.
*/
private function initFonts():void
{
VectorText.extractFont(_loader.data);
}
/**
* Initialize the main 3d elements.
*/
private function init3d():void
{
_scene = new Scene3D();
_camera = new Camera3D({x:0, y:0, z:-1000});
_view = new View3D({camera:_camera, scene:_scene});
_view.x = _width3d/2;
_view.y = _height3d/2;
_view.clipping = new RectangleClipping({minX:-_width3d/2, maxX:_width3d/2, minY:-_height3d/2, maxY:_height3d/2});
_view.addSourceURL("srcview/index.html");
addChild(_view);
}
/**
* Initiliaze the 3d objects in the scene.
*/
private function init3dObjects():void
{
var floor:Plane = new Plane();
floor.width = floor.height = 25000;
floor.segmentsW = floor.segmentsH = 12;
floor.y = -1500;
floor.material = new WireframeMaterial(0x333333);
_scene.addChild(floor);
_interactiveSegment = new InteractiveSegment(_view);
_interactiveSegment.addEventListener(ProgressEvent.PROGRESS, segmentChangingHandler);
_interactiveSegment.addEventListener(Event.COMPLETE, segmentChangedHandler);
_scene.addChild(_interactiveSegment);
_textfield = new TextField3D("Helvetica", {text:"Warping text in Away3D", size:50, textWidth:2000});
_textfield.material = new ColorMaterial(0xFFFFFF);
_textWidth = _textfield.objectWidth;
_scene.addChild(_textfield);
_aligner = new AlignToPath(_textfield, _interactiveSegment.path);
refreshPathHighRes();
updateText();
}
/**
* Updates the path in low quality.
*/
private function refreshPathLowRes():void
{
_pathLength = _aligner.updatePath(_interactiveSegment.path, 0.1);
}
/**
* Updates the path in high quality.
*/
private function refreshPathHighRes():void
{
_pathLength = _aligner.updatePath(_interactiveSegment.path, 0.01);
}
/**
* Called each time the path is changing.
*/
private function segmentChangingHandler(evt:Event):void
{
refreshPathLowRes();
}
/**
* Called each time the path has finished changing.
*/
private function segmentChangedHandler(evt:Event):void
{
refreshPathHighRes();
}
/**
* Simple camera-mouse motion.
*/
private function hoverCamera():void
{
var mX:Number = this.mouseX > 0 ? this.mouseX : 0;
var mY:Number = this.mouseY > 0 ? this.mouseY : 0;
var tarX:Number = 1*(mX - stage.stageWidth/2);
var tarY:Number = -2.5*(mY - stage.stageHeight/2);
var dX:Number = _camera.x - tarX;
var dY:Number = _camera.y - tarY;
_camera.x -= dX*0.1;
_camera.y -= dY*0.1;
_camera.lookAt(_center);
}
/**
* Updates the alignment of the text with an incremental offset in x.
* The length of the path is compared to the length of the text
* to determine when to change the direction of motion,
* otherwise the text would make a loop jump at the end.
*/
private function updateText():void
{
if(_xOffset + _dir*_speed > _pathLength - _textWidth || _xOffset + _dir*_speed < 0)
_dir *= -1;
_xOffset += _dir*_speed;
_xOffset = _xOffset > _pathLength - _textWidth ? 0: _xOffset;
_xOffset = _xOffset < 0 ? 0 : _xOffset;
_aligner.apply(_xOffset, 0);
}
/**
* Enterframe.
*/
private function render3d(evt:Event):void
{
hoverCamera();
_view.render();
updateText();
}
}
}