4

Papervision3D 2.0 + Go Tweening – Flipping Banner (Part 1)


Set up PapervisionTween to automatically render:

PapervisionTween.init(renderer, scene, camera, viewport);

Calling PapervisionTween to tween a plane:

var b:PapervisionTween = new PapervisionTween(_planeArray[0], {rotationY:0}, 0, 1, Quintic.easeInOut, onFlipDone);
b.start();

I've also included the PapervisionTween code in the post in addition to the source files below, but let's move on the flipping code.

Here's the Core class that calls the Flip class:

package com.hydrotik.bannerflip3d {
	/**
	 * @author Donovan Adams
	 * @version December 10, 2007
	 * @description Papervision Page flip example
	 * 
	 */
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
 
	import com.hydrotik.bannerflip3d.Flip;
	import com.hydrotik.bannerflip3d.FlipEvent;
	import com.hydrotik.utils.XMLLoader;
	import com.hydrotik.utils.XMLLoaderEvent;
 
	import flash.system.Capabilities;	
 
	public class Core extends Sprite {
 
		private var _scope:MovieClip;
 
		private var _stage:Stage;
 
		private var _xml:XML;
 
		private var _url:String;
 
		private var _hit: Sprite;
 
		private var _targ : String;
 
		public function Core(scope:MovieClip, stage:Stage):void {
			_scope = scope;
			_stage = stage;
			var p:String;
			if (Capabilities.playerType == "External" || Capabilities.playerType == "StandAlone") {
				p = "../includes/admin/flippingbanner.xml";
			} else {
			    p = "/wp-content/flippingbanner2/includes/admin/flippingbanner.xml";
			}
			var xml:XMLLoader = new XMLLoader(p);
			xml.addEventListener(XMLLoaderEvent.COMPLETE, onXMLComplete);
			xml.addEventListener(XMLLoaderEvent.ERROR, onXMLError);
		}
 
		private function onXMLError(event : XMLLoaderEvent) : void {
			trace(event);
		}
 
		// --== Private Methods ==--
		private function onXMLComplete(event:XMLLoaderEvent):void {
			trace(":: onXMLComplete:");
			_xml = event.xml;
 
			var _oFlip:Flip = new Flip(_scope, _stage, this, event.xml.banner.children(), "", new int(_xml.attribute("seconds")));
			_oFlip.addEventListener(FlipEvent.COMPLETE, onCompleteHandler);
			_oFlip.addEventListener(FlipEvent.ON_FLIP, onFlipHandler);
 
			_hit = new Sprite();
			_hit.graphics.beginFill(0x660000, 0);
			_hit.graphics.drawRect(0, 0, _stage.stageWidth, _stage.stageHeight);
			_scope.addChild(_hit);
			_hit.addEventListener(MouseEvent.CLICK, onClickHandler);
 
			_hit.buttonMode = true;
			_hit.useHandCursor = true;
			_hit.mouseEnabled = true;
		}
 
		private function onClickHandler(event:MouseEvent):void {
			navigateToURL(new URLRequest(_url), _targ);
		}
 
		private function onCompleteHandler(event:FlipEvent):void {
			_url = event.link;
			_targ = event.targ;
		}
 
		private function onFlipHandler(event:FlipEvent):void {
			_url = event.link;
			_targ = event.targ;
		}
 
	}
}

Here's the updated Flip class using the Go tweening engine:

package com.hydrotik.bannerflip3d {
	/**
	 * @author Donovan Adams
	 * @version December 9, 2007
	 * @usage Example:<code></code>
	 * @description
	 * @history
	 * @sends
	 * @todo
	 * 
	 */
	import flash.display.*;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
 
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.core.proto.SceneObject3D;
	import org.papervision3d.events.FileLoadEvent;
	import org.papervision3d.materials.BitmapFileMaterial;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
 
	import com.hydrotik.go.PapervisionTween;
 
	import fl.motion.easing.*;
 
	import org.papervision3d.core.proto.MaterialObject3D;
 
	[Event(name="COMPLETE", type="com.hydrotik.bannerflip3d.FlipEvent")]
 
	[Event(name="ON_FLIP", type="com.hydrotik.bannerflip3d.FlipEvent")]
 
	public class Flip extends EventDispatcher {
 
		public static const VERBOSE:Boolean = true;
 
		private var _scope:Sprite;
 
		private var _stage:Stage;
 
		private var _oCore:*;
 
		private var _assetPath:String;
 
		private var _materialArray:Array;
 
		private var _planeArray:Array;
 
		private var _array:XMLList;
 
		private var _count:int = 0;
 
		private var _next:int;
 
		private var _prev:int;
 
		private var _loader:Sprite;
 
		private var _seconds:int;
 
		//New 2.0 Privates
 
		private var renderer:BasicRenderEngine;
 
		private var camera:Camera3D;
 
		private var viewport:Viewport3D;
 
		private var debug : Function;
 
		private var scene : Scene3D;
 
		private var white : MaterialObject3D;
 
		private var bg : Plane;
 
		public function Flip(scope:Sprite, stage:Stage, core:*, a:XMLList, assetPath:String = "../flashassets/", s:int = 10):void {
			debug = trace;
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			_scope = scope;
			_stage = stage;
			_oCore = core;
			_array = a;
			_assetPath = assetPath;
			_seconds = s;
			_materialArray = [];
			_planeArray = [];
 
			scene = new Scene3D();
			renderer = new BasicRenderEngine();
			camera = new Camera3D();
			camera.z = -100;
			viewport = new Viewport3D(500,300,true);
			viewport.alpha = 0;
 
			_scope.addChild(viewport);
 
			white = new ColorMaterial(0xFFFFFF);
 
			setTimeout(addedToStage, 100);
		}
 
		private function addedToStage():void{
			if(VERBOSE) debug("\n\n>> Flip.addedToStage(); - args: "+[]);
 
			_loader = new Sprite();
			_loader.graphics.beginFill(0x000000);
			_loader.graphics.drawRect(0, 0, 1, 4);
			_scope.addChild(_loader);
			_loader.x = (_stage.stageWidth/2) - 50;
			_loader.y = (_stage.stageHeight/2) - 2;
 
			for (var i:int = 0; i < _array.length(); i++) {
				_materialArray[i] = new BitmapFileMaterial(_array[i].attribute('src'));
				_materialArray[i].oneSide = true;
				_materialArray[i].smooth = true;
				_materialArray[i].addEventListener(FileLoadEvent.LOAD_PROGRESS, onFileProgress);
				_materialArray[i].addEventListener(FileLoadEvent.LOAD_COMPLETE, onFileComplete);
				_planeArray[i] = new Plane( _materialArray[i], 300, 156, 6, 6);
				scene.addChild(_planeArray[i]);
				_planeArray[i].name = i.toString();
				_planeArray[i].rotationY = -180;
			}
 
			// PapervisionTween is extending LinearGo. PapervisionTween is a custom extension using custom syntax, running on the Go system	
			// The init function passes the rendering info so that PapervisionTween can take care of updating the renderer
			PapervisionTween.init(renderer, scene, camera, viewport);
		}
 
		private function onFileProgress(event:FileLoadEvent):void {
			if(VERBOSE) debug("\t percentage: "+Math.round((event.bytesLoaded/event.bytesTotal)*100) + "%");
			var sec:Number = 100/_array.length();
			_loader.width = ((_count * sec) + ((event.bytesLoaded/event.bytesTotal) * sec));
		}
 
		private function onFileComplete(event:FileLoadEvent):void {
			if(VERBOSE) debug("complete!");
			//
			_count++;
			if (_count == _array.length()) {
				onImageQueueCompleteHandler();
			}
		}
 
		private function onImageQueueCompleteHandler():void {
 
			// PapervisionTween is extending LinearGo. PapervisionTween is a custom extension using custom syntax, running on the Go system		
			var l:PapervisionTween = new PapervisionTween(_loader, {alpha:0}, 0, .2, Quintic.easeInOut, loaderFade);
			l.start();
 
			// PapervisionTween is extending LinearGo. PapervisionTween is a custom extension using custom syntax, running on the Go system		
			var b:PapervisionTween = new PapervisionTween(_planeArray[0], {rotationY:0}, 0, 1, Quintic.easeInOut, onFlipDone);
			b.start();
 
			// PapervisionTween is extending LinearGo. PapervisionTween is a custom extension using custom syntax, running on the Go system		
			var c:PapervisionTween = new PapervisionTween(camera, {z:-100}, 0, 1, Quintic.easeInOut, onFlipDone);
			c.start();
 
			_next = 0;
 
			_count = -1;
 
			bg = new Plane(white,5120,2560,10,10);
			bg.y = -200;
			bg.z = 500;
			bg.pitch(0);
 
			scene.addChild(bg);
			dispatchEvent(new FlipEvent(FlipEvent.COMPLETE, _next, _array[0].attribute('link'), _array[0].attribute('target')));
 
			var myTimer:Timer = new Timer(_seconds * 1000);
			myTimer.addEventListener(TimerEvent.TIMER, timerHandler);
			myTimer.start();
		}
 
		private function flip(id:int):void {
			// PapervisionTween is extending LinearGo. PapervisionTween is a custom extension using custom syntax, running on the Go system				
			var a:PapervisionTween = new PapervisionTween(_planeArray[_next], {rotationY:180}, 0, 1, Quintic.easeInOut, onOldFlipDone);
			a.start();
 
			// Update Data
			_prev = _next;
			_next = (id == _array.length() - 1) ? 0 : id + 1;
			var url:String = _array[_next].attribute('link');
			var targ:String = _array[_next].attribute('target');
			trace(url, targ);
			dispatchEvent(new FlipEvent(FlipEvent.ON_FLIP, _next, url, targ));
 
			// PapervisionTween is extending LinearGo. PapervisionTween is a custom extension using custom syntax, running on the Go system		
			var b:PapervisionTween = new PapervisionTween(_planeArray[_next], {rotationY:0}, 0, 1, Quintic.easeInOut, onFlipDone);
			b.start();
 
			// PapervisionTween is extending LinearGo. PapervisionTween is a custom extension using custom syntax, running on the Go system		
			var c:PapervisionTween = new PapervisionTween(camera, {z:-350}, 0, .5, Quintic.easeIn, onCameraHalf);
			c.start();
		}
 
		private function onCameraHalf(event:Event = null):void {
			viewport.alpha 	= 1;
			var c:PapervisionTween = new PapervisionTween(camera, {z:-100}, 0, .5, Quintic.easeOut);
			c.start();
		}
 
		public function timerHandler(event:TimerEvent):void {
			if(VERBOSE) debug("timerHandler: " + event);
			_count = (_count == _array.length() - 1) ? 0 : _count + 1;
			flip(_count);
		}
 
		private function onFlipDone(event:Event = null):void {
			if(VERBOSE) debug("flip done!");
		}
 
		private function loaderFade(event:Event = null):void {
			viewport.alpha 	= 1;
			_scope.removeChild(_loader);
		}
 
		private function onOldFlipDone(event:Event = null):void {
			if(VERBOSE) debug("old flip done!");
			_planeArray[_prev].rotationY = -180;
		}
	}
}

And if you are curious here is the PapervisionTween extension of Go:

/**
 * Copyright (c) 2007 Moses Gunesch, MosesSupposes.com - Donovan Adams, blog.hydrotik.com
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
package com.hydrotik.go {
	import flash.display.DisplayObject;
 
	import org.fuseproject.go.items.LinearGo;
	import org.papervision3d.objects.DisplayObject3D;
 
	//import flash.geom.ColorTransform;
	//import flash.filters.BlurFilter;
	//import flash.geom.Point;	
 
	/**
	 * A basic example of how you could build a tween on LinearGo.
	 */
	public class PapervisionTween extends LinearGo {
 
		// -== Public Properties ==-
		public function get width() : Number {
			return _rotationY;
		}
 
		public function set width(value : Number) : void {
			if (_state == STOPPED)
				_rotationY = value;
		} 		
 
		public function get startWidth() : Number {
			return _startRotationY;
		}
 
		public function set startWidth(value : Number) : void {
			if (_state == STOPPED)
				_startRotationY = value;
		} 		
 
		public function get target() : DisplayObject {
			return _target;
		}
 
		public function set target(obj : DisplayObject) : void {
			if (_state == STOPPED)
				_target = obj;
		}
 
		// -== Protected Properties ==-
		protected var _target : *;
 
		protected var _rotationY : Number;
 
		private static var _viewport:*;
 
		private static var _camera:*;
 
		private static var _scene:*;
 
		private static var _renderer : *;
 
		private var _closure : Function;
 
		private var debug : Function;
 
		protected var _startRotationY : Number;
 
		protected var _changeRotationY : Number;
 
		protected var _startProps : Object = {};
 
		protected var _changeProps : Object = {};
 
		protected var _propsTo : Object = {};
 
 
		public static function init(renderer:*, scene:*, camera:*, viewport:*):void{
			_renderer = renderer;
			_scene = scene;
			_camera = camera;
			_viewport = viewport;
		}
 
		// -== Public Methods ==-
		public function PapervisionTween(
					target:* = null,
					propsTo:Object = null,
					delay:Number = NaN,
					duration:Number = NaN,
					easing:Function = null,
					closure:Function = null)
		{			
			super(delay, duration, easing);
			debug = trace;
			_target = target;
			if(closure != null) addCallback(closure);
			for (var prop in propsTo) { 
				switch (prop) {
					case "alpha":
						if(_target is DisplayObject){
							_propsTo[prop] = (propsTo[prop] != undefined) ? propsTo[prop] : _target[prop];	
						}
						if(_target is DisplayObject3D){
							if(propsTo[prop] != undefined){
								_propsTo[prop] = propsTo[prop];
							}else{
								_target.extra[prop] = new Number(1);
								_propsTo[prop] = _target.extra[prop] = _target.extra[prop];
							}
						}
						break;
					default:
						_propsTo[prop] = (propsTo[prop] != undefined) ? propsTo[prop] : _target[prop];
				}
			}
		}
 
		override public function start( ) :Boolean {
			if (!_target) return false;
			var prop:String;
			for (prop in _propsTo) { 
				switch (prop) {
					case "alpha":
						if(_target is DisplayObject){
							_startProps[prop] = _target[prop];
						}
						if(_target is DisplayObject3D){
							trace("start: "+_target.extra[prop]);
							_startProps[prop] = _target.extra[prop];	
						}
						break;
					default:
						_startProps[prop] = _target[prop];
				}
			}
 
			if (useRelative) {
				for (prop in _propsTo) { 
				    _changeProps[prop] = _propsTo[prop];
				}
			}
			else {
				for (prop in _propsTo) { 
				    _changeProps[prop] = (_propsTo[prop] - _startProps[prop]); //_propsTo[prop];
				}
			}
 
			return (super.start());
		}
 
		//TODO add alpha tweening syntax when released in 2.0 update
		override protected function onUpdate(type:String) : void {
			for (var prop in _propsTo) { 
				switch (prop) {
					case "alpha":
						if(_target is DisplayObject3D){
							//var val:Number = super.correctValue(_startProps[prop] + _changeProps[prop] * _position);
							//_target.material.bitmap.colorTransform(_target.material.bitmap.rect, new ColorTransform(1, 1, 1, val, 0, 0, 0, 0));
							//_target.extra[prop] = val;
							debug("Current version of Pv3D does not support alpha tweening");
						}
						if(_target is DisplayObject) _target[prop] = super.correctValue(_startProps[prop] + _changeProps[prop] * _position);
						break;
					default:
						_target[prop] = super.correctValue(_startProps[prop] + _changeProps[prop] * _position);
				}
			}
			if(_target is DisplayObject3D) _renderer.renderScene(_scene,_camera,_viewport);
		}
 
	}
}

I plan on adding effects as well as the alpha property when 2.0 is able to support that. Shadows, layer effects, and more still to come!


Papervision 2.0 Flipping Banner Source Part 1

8

QueueLoader AS3 rev 18


UPDATES Latest Update and Source!

Sorry for the version jump. When I added flv and supporting files the SVN jumped up a few numbers. Regardless I am going to stop posting examples directly here on the blog with the exception of updates and new features worth noting. I think it's also an easy way for people to communicate questions, comments, concerns, etc. As far as usage, downloads, etc., I think it will be easier for me to keep all the necessary info on the google project site then retroactively updating my previous posts.

Important Updates
QUEUE_INIT and ITEM_INIT have been changed to reflect the internal structure. They are now QUEUE_COMPLETE and ITEM_COMPLETE. Sorry if this causes confusion but it needed to be changed at some point. :)

FLV support has been added finally. The event.file var in the callback will return a VideoPlayer Object for video control.

I did some other utilitarian and formatting tasks event meta info, debugging organization with parent level accessibility, etc.

Click here for the current rev

Click here for the usage guide

Click here for the change log

bottega veneta deep coffee pocket bag deep weight loss pills bingo and game casino gambling online virtual how to win at slots versace deep coffee venus bag women does viagra work online bingo uk discount drugstore where to get viagra or cialis diazepam cheap without rx bingo and slots does cialis really work bingo gaming chanel yellow shoulder bag bingo for cash slot machine buy meds online without presciption lancel pearl premier flirt prada white shoulder bag prescriptions pain killers without a prescription viagra product information cialis generic levitra viagra cialis male enhancement online gambling offers manolo blahnik beige hangisi valium indications anya hindmarch beige hobo how does diazepam work who has the cheapest cialis price for tramadol levitra website price for generic viagra top anti depressants pharmacy zolpidem marc jacobs antique gold keylock messenger bag pill for acne casino gambling buy carisoprodol cheap create poker website zyban tablet jimmy choo purple wells shoes valtrex medication counseling for erectile dysfunction hey bingo louis vuitton patent beige sandals louis vuitton monogram idylle pink tote power bingo slot games gucci black evening bag xanax fedex oral jelly viagra new casino slots discount erectile dysfunction medication christian louboutin white ambrosina pumps poker machine games buy no phentermine prescription high stakes poker buy tory burch golden reva ballerina flats casino locations roulette casinos play online casinos bingo and slots viagra effect on women louis vuitton damier graphite keepall bandouliere marc jacobs royal blue keylock shoulder bag play roulette online casino mania online buy compazine buy gucci black trainers online casinos en internet how to win slots christian louboutin blush barcelona sandals prescription diet drugs us only mobile casino games natural clomid buy overseas viagra online casino canada online xanax fedex norvasc generic erectile dysfunction products zoloft canada uk viagra supplier casino bonus tory burch deep blue tory logo rain boots poker for money prescription drugs online adipex no prescription needed pharmacies geniune cialis no prescription ambien dosing how do muscle relaxants work valentino beige snakeskin clutch what is tadalafil ativan dosages sales viagra ysl white muse bag cialis to buy online gambling strategy cheapest phentermine pills christian dior biege medium saddle handbag alprazolam brand cheap viagra new zealand low cost adipex bally patent patent red jana tote ambien pharmacy manolo blahnik bow booties what is viagra used for dosage viagra new diet pill fda approved play slots online now cialis best price las vegas bingo cialis generic tabs versace purple venita bow satchel chloe patent purple cyndi tote fendi apricot snake peekaboo handbag discount lipitor prescription ambien ambien 10mg poker us levitra free samples do meridia phentermine work the same order celine black shoulder bag louis vuitton patent black sandals over the counter medication cheap 37 5 phentermine safe effective diet pills loewe white handbag dolce gabbana black trainers buying phentermine alprazolam generic for xanax ativan 2mg prada beige fairy l bag generic cialis canadian diet phentermine viagra online cheap europe cialis platinum play bingo levitra info prescription drugs migraines levitra alternative phentermine ingredient how does cialis work louis vuitton damier azure canvas galliera gm order amoxicillin new arthritis and psoriasis drug lipitor online pharmacy professional blackjack how does cialis ultram ingredients