- It works just like the SWFLoader class, except that the content property is bindable.
- You can play loaded movieclips using spark.effects.Animate and SimpleMotionPath. Animating property currentFrame from 0 to -1 for example.
- You can load assets from resource bundles at runtime. Using properties key and bundle.
mitch/components/ResourceLoader.as
package mitch.components { import flash.display.DisplayObject; import flash.display.MovieClip; import flash.events.Event; import mx.controls.SWFLoader; /** * <p>The ResourceLoader class is useful for * loading assets from resource bundles at runtime. * Set properties <code>key</code> and <code>bundle</code> so they * correspond to an existing entry in a resource bundle. * Don't forget to embed, or load, the resource bundle.</p> * * Unlike the SWFLoader class, property <code>content</code> of this class * is bindable.</p> * * <p>If the loaded asset is a MovieClip, property <code>clip</code> * will be set to that MovieClip. And property <code>currentFrame</code> * can be used to animate the MovieClip.</p> * * @author Mitch * */ public class ResourceLoader extends SWFLoader { /** * Constructor. * */ public function ResourceLoader() { super(); //dispatched by super-class addEventListener("sourceChanged", sourceChangedHandler); } //-------------------------------------------------------------- // // Public Properties // //-------------------------------------------------------------- //------------------------------ // clip //------------------------------ /**@private */ private var _clip:MovieClip; [Bindable("contentChanged")] /** * Returns the object at property <code>content</code> as MovieClip. */ public function get clip():MovieClip { return _clip; } //------------------------------ // content //------------------------------ [Bindable("contentChanged")] /**@inheritDoc */ public override function get content():DisplayObject { return super.content; } //------------------------------ // currentFrame //------------------------------ /**@private */ private var _currentFrame:int = 0; [Bindable("currentFrameChanged")] /** * Defines the current frame of the MovieClip at property <code>clip</code>. */ public function get currentFrame():int { return _currentFrame; } /**@private */ public function set currentFrame(value:int):void { if(value != _currentFrame) { _currentFrame = value; if(clip) { while(_currentFrame > clip.totalFrames - 1) { _currentFrame -= clip.totalFrames; } while(_currentFrame < 0) { _currentFrame += clip.totalFrames; } clip.gotoAndStop(value); } dispatchEvent(new Event("currentFrameChanged")); } } //------------------------------ // totalFrames //------------------------------ [Bindable("contentChanged")] /** * Returns the total amount of frames at property <code>clip</code>. */ public function get totalFrames():int { return clip?clip.totalFrames:0; } //------------------------------ // bundle //------------------------------ /**@private */ private var _bundle:String; [Bindable("resourceChanged")] /** * Defines the name of the bundle to retrieve the resource from. * @see #key key */ public function get bundle():String { return _bundle; } /**@private */ public function set bundle(value:String):void { _bundle = value; addEventListener(Event.ENTER_FRAME, validateResource); } //------------------------------ // key //------------------------------ /**@private */ private var _key:String; [Bindable("resourceChanged")] /** * Defines the key of the resource * in the bundle defined at <code>bundle</code>. * @see #bundle bundle */ public function get key():String { return _key; } /**@private */ public function set key(value:String):void { _key = value; addEventListener(Event.ENTER_FRAME, validateResource); } /** * @private * Event handler for enterFrame events. * This handler is called only once, if properties key and bundle * are altered in the same frame. */ private function validateResource(event:Event=null):void { removeEventListener(Event.ENTER_FRAME, validateResource); updateResource(); dispatchEvent(new Event("resourceChanged")); } /** * Updates property <code>source</code> using the ResourceManager. * <p>This method is called internally after properties * <code>key</code> and/or <code>bundle</code> change.</p> */ protected function updateResource():void { source = resourceManager.getClass(bundle, key); } //-------------------------------------------------------------- // // Protected Methods // //-------------------------------------------------------------- //------------------------------ // contentChanged() //------------------------------ /** * Updates property <code>clip</code> and dispatches the binding event * of type <code>contentChanged</code>. * This method is called internally when property <code>content</code> changed. * @param oldContent The old value of property <code>content</code>. * @param newContent The new value of property <code>content</code>. */ protected function contentChanged(oldContent:DisplayObject, newContent:DisplayObject):void { if(newContent is MovieClip) { _clip = newContent as MovieClip; } else { _clip = null; } dispatchEvent(new Event("contentChanged")); } //-------------------------------------------------------------- // // Private Functions // //-------------------------------------------------------------- /**@private */ private var oldContent:DisplayObject; /** * @private * Event handler for "sourceChanged" */ private function sourceChangedHandler(event:Event):void { if(!source) { removeEventListener(Event.ENTER_FRAME, contentChangedHandler); removeEventListener(Event.COMPLETE, completeHandler); } addEventListener(Event.ENTER_FRAME, contentChangedHandler); addEventListener(Event.COMPLETE, completeHandler); } /** * @private * Event handler for "enterFrame" after "sourceChanged" */ private function contentChangedHandler(event:Event):void { removeEventListener(event.type, contentChangedHandler); if(content) { //loaded quick removeEventListener(Event.COMPLETE, completeHandler); contentChanged(oldContent, content); } oldContent = content; } /** * @private * Event handler for "complete" after "sourceChanged" (and "enterFrame") */ private function completeHandler(event:Event):void { //needed to load over time removeEventListener(Event.COMPLETE, completeHandler); removeEventListener(event.type, contentChangedHandler);//just in case contentChanged(oldContent, content); } } }
No comments:
Post a Comment