/**
* Copyright yanbaka ( http://wonderfl.net/user/yanbaka )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/rDCN
*/
package
{
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
[SWF(width="465", height="465", frameRate="60")]
public class Gorilla3DRotation extends Sprite
{
static public const API:String = "http://api.flickr.com/services/feeds/photos_public.gne";
static public const NS_MEDIA:String = "http://search.yahoo.com/mrss/";
static public const TAG:String = "Gorilla";
static public const WW:Number = 465;
static public const HH:Number = 465;
static public const ZZ:Number = 1000;
static public const RAD:Number = 1800;
private var _progress:Shape;
private var _loader:URLLoader;
private var _loadCnt:int;
private var _imgs:Array;
private var _imgl:int;
private var _hw:Number;
private var _hh:Number;
private var _bg:Sprite;
private var _rSpeed:Number = 10;
private var _front:Sprite;
private var _base:Sprite;
private var _isDown:Boolean;
private var _addMat3D:Matrix3D;
public function Gorilla3DRotation()
{
_loadCnt = 0;
_imgs = [];
_isDown = false;
_hw = WW*0.5;
_hh = HH*0.5;
_progress = new Shape();
_progress.graphics.lineStyle(1, 0xFF0000);
_progress.graphics.moveTo(0, _hh);
_progress.graphics.lineTo(WW, _hh);
_progress.scaleX = 0.0;
addChild(_progress);
_loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, _onComplete);
var request:URLRequest = new URLRequest(API + "?format=rss_200&tags=" + TAG);
_loader.load(request);
}
private function _onEnterframeHandler(e:Event):void
{
if(!_isDown) return;
_base.x += (_hw-_base.x)/_rSpeed;
_base.y += (_hh-_base.y)/_rSpeed;
_base.z += (ZZ-_base.z)/_rSpeed;
var pivot:Vector3D = new Vector3D(_base.x, _base.y, _base.z);
var ry:Number = (stage.mouseX - _hw)*0.01;
var rx:Number = (stage.mouseY - _hh)*0.01;
_base.transform.matrix3D.appendRotation(-rx, Vector3D.X_AXIS, pivot);
_base.transform.matrix3D.appendRotation(ry, Vector3D.Y_AXIS, pivot);
SimpleZSorter.sortClips(_base, true);
}
private function _toTarget(e:Event):void
{
var mat3D:Matrix3D = Matrix3D.interpolate(_base.transform.matrix3D, _addMat3D, 0.1);
_base.transform.matrix3D = mat3D;
SimpleZSorter.sortClips(_base, true);
}
private function _main():void
{
_bg = new Sprite();
_bg.graphics.beginFill(0xFFFFFF, 0.0);
_bg.graphics.drawRect(0, 0, WW, HH);
_bg.graphics.endFill();
addChild(_bg);
_front = new Sprite();
_front.x = _hw;
_front.y = _hh;
_front.z = 0;
_base = new Sprite();
_base.x = _hw;
_base.y = _hh;
_base.z = ZZ;
addChild(_base);
var l:Number = 20;
var center:Shape = new Shape();
center.graphics.lineStyle(1, 0xFF0000);
center.graphics.moveTo(-l*0.5, 0);
center.graphics.lineTo(l*0.5, 0);
center.graphics.moveTo(0, -l*0.5);
center.graphics.lineTo(0, l*0.5);
center.graphics.endFill();
center.x = _hw;
center.y = _hh;
addChild(center);
for(var i:int=0; i<_imgl; ++i)
{
var tile:Tile = new Tile(_imgs[i]);
tile.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void
{
var vec3D:Vector3D = new Vector3D(_front.x, _front.y, _front.z);
_addMat3D = Tile(e.target).transform.matrix3D.clone();
_addMat3D.invert();
var addVec:Vector3D = _addMat3D.position.add(vec3D);
_addMat3D.position = addVec;
addEventListener(Event.ENTER_FRAME, _toTarget);
});
tile.x = Math.random()*RAD-RAD*0.5;
tile.y = Math.random()*RAD-RAD*0.5;
tile.z = Math.random()*RAD-RAD*0.5;
var m:Number = (tile.x < 0) ? 1 : -1;
var s:Number = (tile.x < 0) ? 180 : 0;
tile.rotationX = Math.atan2(tile.y, tile.x)*180/Math.PI*m+s;
tile.rotationY = Math.atan2(tile.x, tile.z)*180/Math.PI;
_base.addChild(tile);
}
addEventListener(Event.ENTER_FRAME, _onEnterframeHandler);
_bg.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME, _toTarget);
_isDown = true;
});
stage.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void
{
_isDown = false;
});
}
private function _onCompleteImg(e:Event):void
{
_imgs.push(Bitmap(e.target.loader.content).bitmapData);
e.target.loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, _onCompleteImg);
_loadCnt++;
_progress.scaleX = _loadCnt/_imgl;
if(_loadCnt >= _imgl)
{
removeChild(_progress);
_progress = null;
_main();
}
}
private function _onComplete(e:Event):void
{
var xml:XML = XML(e.target.data);
var media:Namespace = new Namespace(NS_MEDIA);
var imgs:Array = [];
_imgl = xml..item.length();
for each(var node:XML in xml..item)
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onCompleteImg);
var url:String = node.media::content.@url;
loader.load(new URLRequest(url), new LoaderContext(true));
}
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.geom.Matrix3D;
class Tile extends Sprite
{
public static const MAX_SIZE:int = 200;
private var _bmp:Bitmap;
public function Tile(val:BitmapData) {
_bmp = new Bitmap();
_bmp.bitmapData = val;
_bmp.smoothing = true;
var s:Number = (MAX_SIZE/val.width < MAX_SIZE/val.height) ? MAX_SIZE/val.width : MAX_SIZE/val.height;
_bmp.scaleX = s;
_bmp.scaleY = s;
_bmp.x = -_bmp.width*0.5;
_bmp.y = -_bmp.height*0.5;
addChild(_bmp);
}
}
class SimpleZSorter
{
/**
* SimpleZSorter.sortClips(container, recursive);
*
* @param container the display object containing the children to be sorted according to their Z Depth.
* @param recursive if set to true, the sortClips will recurse to all nested display objects, and sort their children if necessary.
*/
public static function sortClips(container : DisplayObjectContainer, recursive : Boolean = false) : void
{
//Check if something was passed.
if(container != null){
//Check if this displayobjectcontainer has more then 1 child.
var nc:int = container.numChildren;
if(nc > 1){
var index:int = 0;
var vo : SimpleZSortVO;
var displayObject:DisplayObject;
var transformedMatrix : Matrix3D;
var mainParent : DisplayObject = traverseParents(container);
//This array we will use to store & sort the objects and the relative screenZ's.
var sortArray : Array = new Array();
//cycle through all the displayobjects.
for(var c:int = 0; c < container.numChildren; c++){
displayObject = container.getChildAt(c);
//If we are recursing all children, we also sort the children within these children.
if(recursive && (displayObject is DisplayObjectContainer)){
sortClips(displayObject as DisplayObjectContainer, true);
}
//This transformed matrix contains the actual transformed Z position.
transformedMatrix = displayObject.transform.getRelativeMatrix3D(mainParent);
//Push this object in the sortarray. [Maybe replace the new for a pool]
sortArray.push(new SimpleZSortVO(displayObject, transformedMatrix.position.z));
}
//Sort the array (Array.sort is still king of speed).
sortArray.sortOn("screenZ", Array.NUMERIC | Array.DESCENDING);
for each(vo in sortArray){
//Change the indices of all objects according to their Z Sorted value.
container.setChildIndex(vo.object, index++);
}
//Let's make sure all ref's are released.
sortArray = null;
}
}else{
throw new Error("No displayobject was passed as an argument");
}
}
/**
* This traverses the displayobject to the parent.
*/
private static function traverseParents(container : DisplayObject) : DisplayObject
{
//Take the current parent.
var parent : DisplayObject = container.parent;
var lastParent : DisplayObject = parent;
//Iterate until the parent value is null (we've reached the end of this displayobject chain).
while((parent = parent.parent) != null){
lastParent = parent;
}
//Return the "top most" parent.
return lastParent;
}
}
class SimpleZSortVO
{
public var object : DisplayObject;
public var screenZ:Number;
public function SimpleZSortVO(object : DisplayObject, screenZ:Number){
this.object = object;
this.screenZ = screenZ;
}
}