package { //AS3 import flash.display.*; import flash.events.*; import flash.net.URLLoader; import flash.net.URLRequest; import flash.utils.Dictionary; import flash.geom.Matrix; import flash.text.TextField; import flash.text.StyleSheet; import flash.net.*; //Import papervision 3D import org.papervision3d.scenes.*; import org.papervision3d.cameras.*; import org.papervision3d.objects.*; import org.papervision3d.materials.*; import org.papervision3d.*; import caurina.transitions.*; // Main script class public class script extends MovieClip { //___________________________________________________________3d vars private var scene:MovieScene3D; private var camera:Camera3D; private var container:Sprite; private var camzoom:Number = 5; //__________________________________________________________Gallery vars private var numphot:Number = 1; // Number of photos private var radius:Number = 600; // radius of circle makes the carousel private var cradius:Number = 1100; // cradius of camera rotate around, should be larger than radius private var angle:Number = 0; private var anglePer:Number = new Number(); private var anglePD:Number = new Number(); //__________________________________________________________XML vars private var xmlLoader:URLLoader = new URLLoader(); private var xmlData:XML = new XML(); private var xml_path:String = "data.xml"; // xml_path //__________________________________________________________Gallery Data private var thumb:Array = new Array(); private var capt:Array = new Array(); private var desc:Array = new Array(); private var link:Array = new Array(); private var img:Array = new Array(); // Plane infro private var planeDoubleSide:Boolean = false; private var planeSmooth:Boolean = false; private var quality:Number = 1; // Easing/Movement parameters private var mtime:Number = 2.5; //duration movement of camera private var mtime2:Number = 1; //duration movement of thumbnail when roll over private var mtime3:Number = 1.5; //duration movement of thumbnail when pressed // Cam/Image easing type private var Cam_easeType:String = "easeOutQuint"; private var Img_easeType:String = "easeOutQuint"; private var Img_easeType2:String = "easeOutQuint"; //Distance from origin position when moving out private var moveDistance:Number = 100; // Auto rotate private var autorotate:Boolean = true; private var rotatespeed:Number = 0.002; private var rs:Number = 0.002; private var pitch:Number = 0.075; private var Pitch:Number = 0.075; // Alpha, transparency private var Alpha:Number = 1; // Reflection private var reflection:Boolean = true; private var refDist:Number = 180; //Distance from image to its corresponding reflection private var refIn1:Number = 0.5; // Reflection Intensity 1 private var refIn2:Number = 0; // Reflection Intensity 2 private var refDen1:Number = 0; // Reflection Density 1 private var refDen2:Number = 180; // Reflection Density 2 private var refSmooth:Boolean = false; // Smooth Reflection private var refDoubleSide:Boolean = false; // 2 side Reflection // Camera Infor private var COB:Object = new Object(); private var camPos:Object = new Object(); private var camHeight:Number = 0; private var tPos:Object = new Object(); private var delta1:Number = 0.325; private var delta2:Number = 200; // Navigation Style private var nagStyle:String = "Mouse"; // Description, Caption Data private var cTime:Number = 1; //Caption fade in, fade out private var dTime:Number = 1; //Description fade in, fade out private var cTrans:String = "linear"; //Transition type private var dTrans:String = "easeOutQuint"; //Transition type // Misc variables private var flag:uint = 0; private var loaded:Boolean = false; private var big_loaded:Array = new Array(); private var neededScale:Boolean = true; private var RollOvered:Boolean = false; private var count:Number = 0; private var count2:Number = 0; private var tloaded:Number = 0; private var cID:Number = 0; //Current images private var pInfor:Dictionary = new Dictionary(); private var pContainer:Dictionary = new Dictionary(); private var imgInfor:Dictionary = new Dictionary(); private var ImgContainer:Array = new Array(); // Style Sheet private var css:StyleSheet = new StyleSheet(); //______________________________________________________________________Main script //Constructor public function script():void { // Block Papervison3D trace output Papervision3D.VERBOSE = false; // Initial 3d environment Init(); // Create 3d gallery Create_gallery(); } // Setup data private function Init():void { // Align , scale Stage to full fill screen stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; // Reposition element if stage is resized stage.addEventListener( Event.RESIZE, rePosition) //Create container Sprite for scene 3d container = new Sprite(); container.visible = false; addChild( container ); container.x = stage.stageWidth * 0.5; container.y = stage.stageHeight * 0.5; // Movie Scene 3D scene = new MovieScene3D( container ); // Camera 3D camera = new Camera3D(); camera.zoom = camzoom; // Camera first position camera.x = cradius; camera.z = 0; camera.y = camHeight; COB.angle = 0; camPos.angle = 0; // Reposition cap.x = (stage.stageWidth - cap.width) * 0.5 ; des.x = container.x + 40; des.y = (stage.stageHeight - des.height) * 0.5 + 20; // invisible descripton des.visible = false; // temporary remove caption, description to solve z order issue removeChild(cap); removeChild(des); // Setup preloader preloader.x = 0; preloader.y = (stage.stageHeight - preloader.height) * 0.5 ; preloader.width = stage.stageWidth; preloader.bar.scaleX = 0; // Initialize description InitDescription(); // for preview only Setup_link(); } // Start to build gallery private function Create_gallery():void { // Load data from XML XML_Loading(); //Adding events, renderCamera this.addEventListener(Event.ENTER_FRAME, update3D); } //__________________________________________________________XML load private function XML_Loading():void { xmlLoader.addEventListener(Event.COMPLETE, LoadXML); xmlLoader.load(new URLRequest( xml_path )); } private function LoadXML(e:Event):void { //Extract data xmlData = new XML(e.target.data); ParseData(xmlData); } private function ParseData(dat:XML):void { //Number of photos numphot = dat.photos.photo.length(); // Add Enterframe event for preloader preloader.addEventListener(Event.ENTER_FRAME, preload); anglePer = (360/numphot) * Math.PI/180; anglePD = (360/numphot); for (var i:uint = 0; i<numphot; i++) { thumb[i] = dat.photos.photo.thumb.attributes()[i]; capt[i] = dat.photos.photo.caption.attributes()[i]; desc[i] = dat.photos.photo.desc.text()[i]; link[i] = dat.photos.photo.link.attributes()[i]; img[i] = dat.photos.photo.img.attributes()[i]; big_loaded[i] = 0; } Load_thumbnail(); } //Load external assest private function Load_thumbnail():void { for (var i:uint = 0; i<numphot; i++) { var myLoader:Loader = new Loader(); var myRequest:URLRequest = new URLRequest(thumb[i]); myLoader.load(myRequest); myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, Thumb_loaded); pInfor[myLoader] = i; } } //Loading thumbnails private function Thumb_loaded(e:Event):void { var myOb = e.target.loader; //Bitmap Material var bmp:BitmapData = new BitmapData( myOb.width, myOb.height, true, 0x000000 ); bmp.draw(myOb); var bm:BitmapMaterial = new BitmapMaterial(bmp); bm.doubleSided = planeDoubleSide; bm.smooth = false; bm.name = "front"; // Materials var materials:MaterialsList = new MaterialsList( { back: new MovieAssetMaterial( "BACK", true ), front: bm } ); var insideFaces :int = Cube.FRONT + Cube.BACK; // Create a plane or cube with depth = 1 var p:Cube= new Cube( materials, myOb.width, 1, myOb.height, quality, 1, quality, insideFaces ); var index = pInfor[myOb]; scene.addChild( p, "plane" + index ); // Setting up the plane contains corresponding picture // Extracting the corresponding index // Additional data, for roll over, roll out movement purpose p.extra = { tPos:new Object, cPos:new Object, oPos:new Object, ref:new Plane(), index:new Number, rotationY:new Number } // Calculate original position p.x = Math.cos( index * anglePer) * radius; p.z = Math.sin( index * anglePer) * radius; p.rotationY = ( -index * anglePer) * (180/Math.PI) + 270; p.extra.oPos.x = p.x; p.extra.oPos.z = p.z; p.extra.cPos.x = p.x; p.extra.cPos.z = p.z; p.extra.tPos.x = Math.cos( index * anglePer) * (radius + moveDistance); p.extra.tPos.z = Math.sin( index * anglePer) * (radius + moveDistance); p.extra.index = index; p.extra.rotationY = p.rotationY; count++; tloaded++; //Check if all thumbnails are loaded if (count == numphot) { //Load images for (var i:uint = 0; i < numphot; i++) { var myLoader:Loader = new Loader(); var myRequest:URLRequest = new URLRequest(img[i]); myLoader.load(myRequest); myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, Img_loaded); imgInfor[myLoader] = i; } } //______________________________________________________________Make Reflection if (reflection) { // Create new reflection Bitmap Data var bmp2:BitmapData = new BitmapData( myOb.width, myOb.height, true, 0x000000); // Flip vertical var m:Matrix = new Matrix(); m.createBox(1, -1, 0, 0, myOb.height); bmp2.draw( bmp, m ); //Reflection Bitmap Object var b2:Bitmap = new Bitmap(bmp2); // Reflection mask m.createGradientBox(myOb.width, myOb.height,Math.PI/2,myOb.height); var mymask:Shape = new Shape(); mymask.graphics.lineStyle(0,0,0); mymask.graphics.beginGradientFill("linear", [0x000000, 0x000000],[refIn1, refIn2], [refDen1, refDen2],m) ; mymask.graphics.lineTo(0, myOb.height); mymask.graphics.lineTo(myOb.width, myOb.height); mymask.graphics.lineTo(myOb.width, 0) mymask.graphics.lineTo(0, 0) mymask.graphics.endFill(); // CacheaAsBitmap mymask.cacheAsBitmap = true; b2.cacheAsBitmap = true; // Create mask b2.mask = mymask; addChild(b2); addChild(mymask); var bmp3:BitmapData = new BitmapData(myOb.width, myOb.height, true, 0x000000); bmp3.draw(b2); // Create Reflection plane var bm2:BitmapMaterial = new BitmapMaterial(bmp3); bm2.doubleSided = refSmooth; bm2.smooth = refDoubleSide; var p2:Plane = new Plane(bm2, 1, 0, 2, 2); p2.x = Math.cos( index * anglePer) * radius; p2.z = Math.sin( index * anglePer) * radius; p2.y = - refDist; p2.rotationY = ( -index * anglePer) * (180/Math.PI) + 270; scene.addChild(p2); removeChild(b2); removeChild(mymask); p.extra.ref = p2; } //Sprite contains thumbnails var container:Sprite = p.container; // Setting Alpha value of thumbnails container.alpha = Alpha; container.buttonMode = true; // Roll over, roll out, press event container.addEventListener(MouseEvent.ROLL_OVER, RollOver); container.addEventListener(MouseEvent.ROLL_OUT, RollOut); container.addEventListener(MouseEvent.MOUSE_DOWN, Press); pContainer[container] = p; } //___________________________________________________________Preloader private function preload(e:Event):void { var preloader = e.target; var bar = preloader.bar; bar.scaleX += (tloaded / (2 * numphot) - bar.scaleX) * 0.1; if (bar.scaleX >= 0.95) { bar.scaleX = 1; //Fade out preloader Tweener.addTween( preloader, { alpha:0, time:1, transition:"easeOutExpo", onComplete:function():void { //remove preloader ~ load complete removeChild(preloader) // Fade in screen container.visible = true; container.alpha = 0; Tweener.addTween( container, {alpha:1, time:1, transition:"easeOutExpo" } ); // Add caption , desciption addChild(cap); addChild(des); } }); // remove Enterframe event for preloader preloader.removeEventListener(Event.ENTER_FRAME, preload); } } private function Img_loaded(e:Event):void { var img = e.target.loader; // Make reference for further using ImgContainer[imgInfor[img]] = img; //Scale down and hide image img.scaleX = 0; img.scaleY = 0; img.alpha = 0; addChild(img); // increase total loaded tloaded++; } //______________________________________________Thumbnail Roll Over, Roll Out, Press //Thumb roll over private function RollOver(e:Event):void { var p:Cube = pContainer[e.target]; var ob:Object = { x:p.extra.tPos.x, z:p.extra.tPos.z, time: mtime2, transition:Img_easeType, onUpdate: updatePos, onUpdateParams: [p] } Tweener.addTween(p.extra.cPos, ob ); var index = p.extra.index; // Tween Caption:Fade In/Fade Out var FadeIn:Function = function(index:Number):void { cap.text = capt[index]; Tweener.addTween(cap, {alpha:1, time: (cTime/2), transition:cTrans}); } Tweener.addTween(cap, {alpha:0, time: (cTime/2) , transition:cTrans, onComplete: FadeIn, onCompleteParams:[index]}); } // Thumb roll out private function RollOut(e:Event):void { var p:Cube = pContainer[e.target]; var ob:Object = { x:p.extra.oPos.x, z:p.extra.oPos.z, time: mtime2, transition:Img_easeType, onUpdate: updatePos, onUpdateParams: [p] } Tweener.addTween(p.extra.cPos, ob ); } // Thumb pressed private function Press(e:Event):void { var container = e.target; var p = pContainer[container]; if (flag == 0) { //Prevent roll over, roll out tween container.removeEventListener(MouseEvent.ROLL_OVER, RollOver); container.removeEventListener(MouseEvent.ROLL_OUT, RollOut); cap.alpha = 1; des.visible = true; rs = 0; pitch = 0; for (var i:uint = 0; i < numphot; i++) { if ( i != p.extra.index) { var pl = scene.getChildByName("plane"+i); pl.container.removeEventListener(MouseEvent.ROLL_OVER, RollOver); pl.container.removeEventListener(MouseEvent.ROLL_OUT, RollOut); pl.container.removeEventListener(MouseEvent.MOUSE_DOWN, Press); pl.container.buttonMode = false; //_____________________________________________________________________ //Add tweening alpha - Optional Tweener.addTween(pl.container, {alpha:0, time:2, transition:"easeOutQuint"}); Tweener.addTween(pl.extra.ref.container, {alpha:0, time:2, transition:"easeOutQuint"}); //______________________________________________________________________ //Add tweening scale - Optional /* Tweener.addTween(pl.container, {scaleX:0, scaleY:0, time:2, transition:"easeOutQuint"}); Tweener.addTween(pl.extra.ref.container, {scaleX:0, scaleY:0, time:2, transition:"easeOutQuint"}); */ } } var tob:DisplayObject3D = new DisplayObject3D(); tob.x = delta1 * (1 - camera.x) + camera.x; tob.z = delta1 * (-camera.z) + camera.z; tob.rotationY = (-angle % 360) + 270; tob.moveLeft(delta2); tPos.x = tob.x; tPos.z = tob.z; tPos.rotationY = tob.rotationY; var myob:Object = { x:tPos.x, z:tPos.z, y:0, rotationY:tPos.rotationY, time:mtime3, transition:Img_easeType2, onUpdate:updatePos2, onUpdateParams: [p] }; // Move thumbnail to target position Tweener.addTween( p, myob); // Move Camera Tweener.addTween(camera, {y:0, time: dTime, transition:dTrans }); //Fade In Description des.text = desc[p.extra.index]; Tweener.addTween(des, {alpha:1, time: dTime, transition:dTrans, onComplete:AddEvent, onCompleteParams:[p]}); cID = p.extra.index; } else { rs = rotatespeed; pitch = Pitch; // Plane smooth == false ~ increase performance p.getMaterialByName("front").smooth = false; container.removeEventListener(MouseEvent.ROLL_OVER, RollOver2); container.removeEventListener(MouseEvent.ROLL_OUT, RollOut2); stage.removeEventListener(MouseEvent.MOUSE_MOVE, MouseMove); var myob2:Object = {x:p.extra.oPos.x, z:p.extra.oPos.z, y:0, rotationY:p.extra.rotationY, time:mtime3, transition:Img_easeType2, onUpdate:updatePos2, onUpdateParams: [p], onComplete: RestoreEvent, onCompleteParams: [p]}; // Move thumbnail back Tweener.addTween( p, myob2); for (var j:uint = 0; j < numphot; j++) { if ( j != p.extra.index) { var pl2 = scene.getChildByName("plane"+j); pl2.container.addEventListener(MouseEvent.ROLL_OVER, RollOver); pl2.container.addEventListener(MouseEvent.ROLL_OUT, RollOut); pl2.container.addEventListener(MouseEvent.MOUSE_DOWN, Press); pl2.container.buttonMode = true; //______________________________________________________________ //Add tweening alpha - Optional Tweener.addTween(pl2.container, {alpha:1, time:2, transition:"easeOutQuint"}); Tweener.addTween(pl2.extra.ref.container, {alpha:1, time:2, transition:"easeOutQuint"}); //______________________________________________________________ //Add tweening scale - Optional /* Tweener.addTween(pl2.container, {scaleX:1, scaleY:1, time:2, transition:"easeOutQuint"}); Tweener.addTween(pl2.extra.ref.container, {scaleX:1, scaleY:1, time:2, transition:"easeOutQuint"}); */ } } // Move Camera Back Tweener.addTween(camera, {y:camHeight, time: dTime, transition:dTrans }); //Fade Out Description Tweener.addTween(des, {alpha:0, time: dTime, transition:dTrans, onComplete:function():void {des.visible = false}}); //Fade Out image neededScale = true; Tweener.addTween(ImgContainer[cID], {scaleX:0, scaleY:0, alpha:0, time:1, transition:"easeOutQuint" }); } flag = Math.abs(flag-1); } //______________________________________________________________________ // New roll over, roll out when a thumbnail is presed private function AddEvent(p:Cube):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, MouseMove); p.container.addEventListener(MouseEvent.ROLL_OVER, RollOver2); p.container.addEventListener(MouseEvent.ROLL_OUT, RollOut2); //Plane smooth == true ~ increase quality p.getMaterialByName("front").smooth = true; } private function RollOver2(e:Event):void { if (neededScale) { Tweener.addTween(ImgContainer[cID], {scaleX:1, scaleY:1, alpha:0.85, time:1, transition:"easeOutBack" }); neededScale = false; } stage.addEventListener(MouseEvent.MOUSE_MOVE, MouseMove); } private function RollOut2(e:Event):void { neededScale = true; Tweener.addTween(ImgContainer[cID], {scaleX:0, scaleY:0, alpha:0, time:1, transition:"easeOutQuint" }); stage.removeEventListener(MouseEvent.MOUSE_MOVE, MouseMove); } private function MouseMove(e:Event):void { ImgContainer[cID].x = (stage.mouseX + 10) ; ImgContainer[cID].y = (stage.mouseY + 10); } //_______________________________________________________________Update position private function updatePos(p:Cube):void { p.x = p.extra.cPos.x; p.z = p.extra.cPos.z; p.extra.ref.x = p.x; p.extra.ref.z = p.z; } private function updatePos2(p:Cube):void { p.extra.cPos.x = p.x; p.extra.cPos.z = p.z; p.extra.ref.x = p.x; p.extra.ref.z = p.z; p.extra.ref.rotationY = p.rotationY; } private function RestoreEvent(p:Cube):void { var container:Sprite = p.container; //Restore Roll Over, Roll Out container.addEventListener(MouseEvent.ROLL_OVER, RollOver); container.addEventListener(MouseEvent.ROLL_OUT, RollOut); } //________________________________________________________________________ private function MoveCamera(k:Number):void { camPos.angle = k * anglePer; Tweener.addTween(COB, {angle: camPos.angle, time: mtime, transition:Cam_easeType, onUpdate:updateCamera}); } private function updateCamera():void { var x = Math.cos( COB.angle) * cradius; var z = Math.sin( COB.angle) * cradius; camera.x = x; camera.z = z; angle = COB.angle * 180/Math.PI; } private function update3D(e:Event):void { if (autorotate) { var del = (stage.mouseX - stage.stageWidth * 0.5) * rs; //var del2 = (stage.stageHeight * 0.5 - stage.mouseY) * pitch; angle += del; var x = Math.cos(angle*Math.PI/180)*cradius; var z = Math.sin(angle*Math.PI/180)*cradius; camera.x = x; camera.z = z; } scene.renderCamera( camera ); } private function rePosition(e:Event):void { container.x = stage.stageWidth * 0.5; container.y = stage.stageHeight * 0.5; // Reposition caption, description cap.x = (stage.stageWidth - cap.width) * 0.5 ; cap.y = container.y + 150; des.x = container.x + 40; des.y = (stage.stageHeight - des.height) * 0.5 + 20 ; } //__________________________________________Apply styleSheet in description field private function InitDescription():void { // load external css var req:URLRequest = new URLRequest("css/styles.css"); var loader:URLLoader = new URLLoader(); loader.load(req); loader.addEventListener(Event.COMPLETE, cssLoaded); // Adding text link event addEventListener(TextEvent.LINK, clickText); } private function cssLoaded(e:Event):void { css.parseCSS(e.target.data); des.styleSheet = css; } private function clickText(li:TextEvent):void { var myURL:URLRequest = new URLRequest(li.text); navigateToURL(myURL,"_blank"); } //___________________________________for Preview only private function Setup_link():void { gal2.buttonMode = gal3.buttonMode = gal4.buttonMode = true; gal2.addEventListener(MouseEvent.MOUSE_DOWN, go2); gal3.addEventListener(MouseEvent.MOUSE_DOWN, go3); gal4.addEventListener(MouseEvent.MOUSE_DOWN, go4); } private function go2(e:Event):void { var myURL:URLRequest = new URLRequest("./3d2.html"); navigateToURL(myURL,"_self"); } private function go3(e:Event):void { var myURL:URLRequest = new URLRequest("./3d3.html"); navigateToURL(myURL,"_self"); } private function go4(e:Event):void { var myURL:URLRequest = new URLRequest("./3d4.html"); navigateToURL(myURL,"_self"); } } }