Flash Camo Bobble Person Demo
/**
* Copyright FlashBum ( http://wonderfl.net/user/FlashBum )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/A4J4
*/
package
{
import camo.core.events.LoaderManagerEvent;
import camo.core.managers.CamoPropertySheetManager;
import camo.core.managers.DecalSheetManager;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
[SWF(width="600", height = "400", backgroundColor = "#3A3E4A", framerate = "31")]
public class BobbleHeadApp extends Sprite
{
public static const BASE_PATH:String = "http://demos.flashartofwar.com/BobbleHeadApp/";
private var fontSWF : Loader;
private var propSheet : CamoPropertySheetManager;
private var label : Label;
private var bobblePerson : BobblePerson;
public function BobbleHeadApp()
{
configureStage( );
loadFonts( );
}
private function configureStage() : void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
}
private function loadFonts() : void
{
fontSWF = new Loader( );
fontSWF.contentLoaderInfo.addEventListener( Event.COMPLETE, onFontsLoaded );
fontSWF.load( new URLRequest( BASE_PATH + "swfs/fonts/FontLibrary.swf" ) );
}
private function onFontsLoaded(event : Event) : void
{
fontSWF.contentLoaderInfo.removeEventListener( Event.COMPLETE, onFontsLoaded );
loadPropertySheet( );
}
private function loadPropertySheet() : void
{
trace( "Loading CSS" );
propSheet = GlobalPropertySheetManager.instance;
var loader : URLLoader = new URLLoader( );
loader.addEventListener( Event.COMPLETE, onPropertySheetLoad );
loader.load( new URLRequest( BASE_PATH + "css/main.properties.css" ) );
}
private function onPropertySheetLoad(event : Event) : void
{
var target : URLLoader = event.target as URLLoader;
target.removeEventListener( Event.COMPLETE, onPropertySheetLoad );
propSheet.parseCSS( "global.properties", target.data );
loadDecalSheetData( );
}
private function loadDecalSheetData() : void
{
var urlLoader : URLLoader = new URLLoader( );
urlLoader.addEventListener( Event.COMPLETE, onDecalSheetDataLoad, false, 0, true );
urlLoader.load( new URLRequest( BASE_PATH + "xml/decalsheet.xml" ) );
}
private function onDecalSheetDataLoad(event : Event) : void
{
// Remove Event Listener
URLLoader( event.target ).removeEventListener( Event.COMPLETE, onDecalSheetDataLoad );
//
var xml : XML = XML( event.target.data );
var decalSheetManager : DecalSheetManager = GlobalDecalSheetManager.instance;
decalSheetManager.addEventListener( LoaderManagerEvent.PRELOAD_NEXT, onPreloadNext, false, 0, true );
decalSheetManager.addEventListener( LoaderManagerEvent.PRELOAD_DONE, onDecalSheetsLoad, false, 0, true );
decalSheetManager.parseXML( xml );
}
protected function onPreloadNext(event : LoaderManagerEvent) : void
{
trace( "Loading DecalSheet " + event.data.totalPreloaded + " of " + event.data.totalPreloading );
}
private function onDecalSheetsLoad(event : LoaderManagerEvent) : void
{
var target : DecalSheetManager = event.target as DecalSheetManager;
target.removeEventListener( LoaderManagerEvent.PRELOAD_DONE, onDecalSheetsLoad );
init( );
}
protected function init() : void
{
trace( "Hello World" );
createLabel( );
createPerson( );
addEventListener( Event.ENTER_FRAME, onEnterFrame );
}
private function onEnterFrame(event : Event) : void
{
bobblePerson.calculateBobble( );
}
private function createLabel() : void
{
label = new Label( "siteLabel" );
addChild( label );
}
protected function createPerson() : void
{
bobblePerson = new BobblePerson( "BobblePerson" );
addChild( bobblePerson );
}
}
}
import camo.core.managers.DecalSheetManager;
class GlobalDecalSheetManager
{
public static const INIT : String = "init";
private static var __instance : DecalSheetManager;
/**
*
* @param enforcer
*
*/
public function GlobalDecalSheetManager(enforcer : SingletonEnforcer)
{
if (enforcer == null)
{
throw new Error( "Error: Instantiation failed: Use GlobalDecalSheetManager.instance instead." );
}
}
/**
*
* @return
*
*/
public static function get instance() : DecalSheetManager
{
if (GlobalDecalSheetManager.__instance == null)
{
GlobalDecalSheetManager.__instance = new DecalSheetManager( );
}
return GlobalDecalSheetManager.__instance;
}
}
import camo.core.managers.CamoPropertySheetManager;
class GlobalPropertySheetManager
{
public static const INIT : String = "init";
private static var __instance : CamoPropertySheetManager;
public function GlobalPropertySheetManager(enforcer : SingletonEnforcer)
{
if (enforcer == null)
{
throw new Error( "Error: Instantiation failed: Use GlobalDecalSheetManager.instance instead." );
}
}
public static function get instance() : CamoPropertySheetManager
{
if(GlobalPropertySheetManager.__instance == null)
{
GlobalPropertySheetManager.__instance = new CamoPropertySheetManager( );
}
return GlobalPropertySheetManager.__instance;
}
}
internal class SingletonEnforcer
{
}
import flash.events.Event;
class FocusEvent extends Event
{
public static const IN_FOCUS : String = "inFocus";
public static const LOST_FOCUS : String = "lostFocus";
public var text : *;
public var skinName : String;
public function FocusEvent(type : String, text : String = "", skinName : String = "default", bubbles : Boolean = false, cancelable : Boolean = false)
{
this.text = text;
this.skinName = skinName;
super( type, bubbles, cancelable );
}
}
import camo.core.display.CamoDisplay;
import camo.core.property.PropertySelector;
import flash.errors.IllegalOperationError;
class AbstractComponent extends CamoDisplay
{
protected static const ID_DELIMITER : String = " ";
protected var defaultSelectorNames : Array;
public function AbstractComponent(self : AbstractComponent, id : String)
{
if(self != this)
{
//only a subclass can pass a valid reference to self
throw new IllegalOperationError( "Abstract class did not receive reference to self. " + className + " cannot be instantiated directly." );
}
else
{
parseStyleNames( id );
init( );
}
}
protected function parseStyleNames(id : String) : void
{
defaultSelectorNames = id.split( ID_DELIMITER );
this.id = defaultSelectorNames.pop( );
// clean up selectors
defaultSelectorNames.unshift( "." + className );
defaultSelectorNames.push( "#" + this.id );
}
protected function init() : void
{
var prop : PropertySelector = GlobalPropertySheetManager.instance.getSelector.apply( null, defaultSelectorNames );
applyProperties( prop );
}
}
import flash.events.IEventDispatcher;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.navigateToURL;
class BobbleContainer extends AbstractComponent
{
protected var _active : Boolean;
public var rollOverForce : Number = 1;
public var noddingForce : Number = 0;
public var noddingAngle : Number = 0;
public var noddingRange : Number = 30;
public var noddingHit : Number = .7;
public var noddingDamp : Number = .985;
public var label : Label;
public var rollOverText : String = "";
public var url : URLRequest;
public var skin : String = "default";
protected var decalDisplay : DecalDisplay;
public function BobbleContainer(id : String = "bobbleContainer")
{
super( this, id );
}
public function set active(value : Boolean) : void
{
_active = value;
if (_active)
addEventListeners( this );
else
removeEventListeners( this );
}
public function get active() : Boolean
{
return _active;
}
public function set src(value : String) : void
{
decalDisplay = new DecalDisplay( id + "DecalDisplay" );
decalDisplay.src = value;
addChildAt( decalDisplay, 0 );
}
override protected function init() : void
{
createLabel( );
super.init( );
}
protected function createLabel() : void
{
label = new Label( id + "Label" );
addChild( label );
}
protected function addEventListeners(target : IEventDispatcher) : void
{
target.addEventListener( MouseEvent.ROLL_OVER, onRollOver );
target.addEventListener( MouseEvent.ROLL_OUT, onRollOut );
target.addEventListener( MouseEvent.CLICK, onClick );
}
protected function removeEventListeners(target : IEventDispatcher) : void
{
target.removeEventListener( MouseEvent.ROLL_OVER, onRollOver );
target.removeEventListener( MouseEvent.ROLL_OUT, onRollOut );
target.removeEventListener( MouseEvent.CLICK, onClick );
}
public function calculateBobble() : void
{
if (noddingForce)
{
if (noddingForce < .05)
noddingForce = 0;
rotation = Math.sin( noddingAngle ) * noddingForce * (noddingRange * .5);
noddingAngle += noddingHit * noddingForce;
noddingForce *= noddingDamp;
}
}
protected function onRollOver(event : MouseEvent) : void
{
if (noddingForce < (rollOverForce * .5))
{
noddingAngle = 0;
noddingForce = rollOverForce;
}
dispatchEvent( new FocusEvent( FocusEvent.IN_FOCUS, rollOverText, skin, true, true ) );
}
protected function onRollOut(event : MouseEvent) : void
{
dispatchEvent( new FocusEvent( FocusEvent.LOST_FOCUS, rollOverText, "default", true, true ) );
}
protected function onClick(event : MouseEvent) : void
{
if (url)
navigateToURL( url, "_self" );
}
}
import camo.core.decal.DecalSheet;
import flash.display.BitmapData;
class BobblePerson extends AbstractComponent
{
protected var _partIds : Array = new Array( );
protected var partInstances : Array = new Array( );
public var partDisplayId : String;
protected var defaultSkin : DecalSheet;
protected var defaultSkinBMD : BitmapData;
public function set partIds(value : Array) : void
{
_partIds = value;
saveDefaultBitmapData( );
createParts( );
}
protected function saveDefaultBitmapData() : void
{
defaultSkin = GlobalDecalSheetManager.instance.getSheet( "default" );
defaultSkinBMD = defaultSkin.bitmapData.clone( );
}
protected function switchSkin(skinName : String = "default") : void
{
var newSkinBitmapData : BitmapData;
if (skinName == "default")
{
newSkinBitmapData = defaultSkinBMD.clone( );
}
else
{
newSkinBitmapData = GlobalDecalSheetManager.instance.getSheet( skinName ).bitmapData.clone( );
}
if (newSkinBitmapData)
defaultSkin.bitmapData = newSkinBitmapData;
}
public function get partDisplay() : BobbleContainer
{
var index : int = _partIds.indexOf( partDisplayId );
return (index != - 1) ? partInstances[index] : null;
}
public function BobblePerson(id : String = "BobblePerson")
{
super( this, id );
}
override protected function init() : void
{
super.init( );
}
public function createParts() : void
{
var total : int = _partIds.length;
var i : int;
var part : BobbleContainer;
var partID : String;
for (i = 0; i < total ; i ++)
{
partID = _partIds[i];
part = new BobbleContainer( partID );
addChild( part );
partInstances.push( part );
}
display.addEventListener( FocusEvent.IN_FOCUS, onContainerRollOver );
display.addEventListener( FocusEvent.LOST_FOCUS, onContainerRollOut );
}
public function onContainerRollOver(event : FocusEvent) : void
{
if (event.target != partDisplay)
{
partDisplay.label.text = event.text;
switchSkin( event.skinName );
}
}
public function onContainerRollOut(event : FocusEvent) : void
{
partDisplay.label.text = "";
switchSkin( "default" );
}
public function calculateBobble() : void
{
var total : int = partInstances.length;
for (var i : int = 0; i < total ; i ++)
{
BobbleContainer( partInstances[i] ).calculateBobble( );
}
}
}
import camo.core.decal.Decal;
class DecalDisplay extends AbstractComponent
{
protected var decalInstance : Decal;
public var pixelSnapping : String = "auto";
public var smoothing : Boolean = true;
public function DecalDisplay(id : String)
{
super( this, id );
}
public function set src(decalName : String) : void
{
decalInstance = GlobalDecalSheetManager.instance.getDecal( decalName, pixelSnapping, smoothing );
if (! contains( decalInstance ))
addChild( decalInstance );
}
}
import camo.core.enum.CSSProperties;
import flash.text.StyleSheet;
import flash.text.TextField;
import flash.text.TextFormat;
class Label extends AbstractComponent
{
protected var _styleSheet : StyleSheet;
protected var textField : TextField = new TextField( );
protected var proxyTextFormat : TextFormat = new TextFormat( );
protected var _textAlign : String = CSSProperties.LEFT;
public function set autoSize(value : String) : void
{
textField.autoSize = validateAutoSize( value );
invalidate( );
}
public function set antiAliasType(value : String) : void
{
textField.antiAliasType = validateAntiAliasType( value );
invalidate( );
}
public function set embedFonts(value : Boolean) : void
{
textField.embedFonts = value;
invalidate( );
}
public function set sharpness(value : Number) : void
{
textField.sharpness = value;
invalidate( );
}
public function get text() : String
{
return textField.text;
}
public function set text(value : String) : void
{
textField.text = value;
invalidate( );
}
public function set textAlign(value : String) : void
{
_textAlign = value;
invalidate( );
}
public function set textFieldWidth(value : Number) : void
{
textField.width = value;
invalidate( );
}
public function set textFieldHeight(value : Number) : void
{
textField.height = value;
invalidate( );
}
public function set textFieldAlign(value : String) : void
{
proxyTextFormat.align = value;
invalidate( );
}
public function set fontFace(value : String) : void
{
font = value;
invalidate( );
}
public function set fontSize(value : Number) : void
{
size = value;
invalidate( );
}
public function set font(value : String) : void
{
proxyTextFormat.font = value;
invalidate( );
}
public function set color(value : uint) : void
{
proxyTextFormat.color = value;
invalidate( );
}
public function set size(value : Number) : void
{
proxyTextFormat.size = value;
invalidate( );
}
public function set letterSpacing(value : Number) : void
{
proxyTextFormat.letterSpacing = value;
invalidate( );
}
public function Label( id : String = "label" )
{
super( this, id );
}
override protected function init() : void
{
textField.selectable = false;
textField.autoSize = "left";
addChild( textField );
super.init( );
}
override protected function draw() : void
{
proxyTextFormat.align = _textAlign;
textField.defaultTextFormat = proxyTextFormat;
textField.setTextFormat( proxyTextFormat );
super.draw( );
}
public function setTextFormat(format : TextFormat, beginIndex : int = - 1, endIndex : int = - 1) : void
{
textField.setTextFormat( format, beginIndex, endIndex );
}
public static function validateAntiAliasType(value : String) : String
{
switch (value)
{
case CSSProperties.ADVANCED:
return value;
break;
default:
return CSSProperties.NORMAL;
break;
}
}
public static function validateAutoSize(value : String) : String
{
switch (value)
{
case CSSProperties.LEFT:
case CSSProperties.RIGHT:
case CSSProperties.CENTER:
return value;
break;
default:
return CSSProperties.NONE;
break;
}
}
}