5 Replies Latest reply: Jul 17, 2012 10:26 AM by kglad RSS

    How to specify SWF instead of an image in loading

    nikolaig Community Member

      I hope it is not too much over my head as I would like to make it work. Some time ago I recieved help in constracting an interactive image thumb scroller using greensock features.
      My biggest problem at the moment is that I can not figure out how to change the code so the thumbs would bring up the swf files and not jpg files. In other words my small thumbnails are small jpg files (as they were intended to be), but my bigger visuals (the ones which are being brought by clicking on the small thumbnails) I would like to change to an swf file (as it contains its separate animation and additional set of buttons)
      Here is the original code I am trying to modify:
      [CODE]
      package {
      import com.greensock.TweenLite;
      import com.greensock.events.LoaderEvent;
      import com.greensock.loading.ImageLoader;
      import com.greensock.loading.LoaderMax;
      import com.greensock.loading.XMLLoader;
      import com.greensock.plugins.AutoAlphaPlugin;
      import com.greensock.plugins.ColorTransformPlugin;
      import com.greensock.plugins.GlowFilterPlugin;
      import com.greensock.plugins.TweenPlugin;

       

      import flash.display.MovieClip;
      import flash.display.Sprite;
      import flash.events.Event;
      import flash.events.MouseEvent;

       


      public class SlideshowExample extends MovieClip {
        private static const _THUMB_WIDTH:Number = 100;
        private static const _THUMB_HEIGHT:Number = 64;
        private static const _IMAGE_WIDTH:Number = 550;
        private static const _IMAGE_HEIGHT:Number = 355;
        private static const _THUMB_GAP:Number = 4;
        private static const _SCROLL_SPEED:Number = 12;
        private static const _SCROLL_AREA:Number = 150;

       

        private var _progressBar:MovieClip;
        private var _arrowLeft:MovieClip;
        private var _arrowRight:MovieClip;

       

        private var _slides:Array;
        private var _curSlide:Slide; //Slide that is currently displaying
        private var _loadingSlide:Slide; //only used when a Slide is supposed to show but hasn't been fully loaded yet (like if the user clicks "next" many times before all the images have loaded). We keep track of the one that's in the process of loading and should be shown as soon as it finishes, then we set _loadingSlide back to null.
        private var _imagesContainer:Sprite; //the Sprite into which the full-size images are placed (this helps manage the stacking order so that the images can always be behind everything else and yet we can addChild() each image so that it shows up on top of the previous one)
        private var _thumbnailsContainer:Sprite; //the Sprite into which the thumbnail images are placed. This also allows us to slide them all at the same time.
        private var _destScrollX:Number = 0; //destination x value for the _thumbnailsContainer which is used for scrolling it across the bottom. We don't want to use _thumbnailsContainer.x because it could be in the process of tweening, so we keep track of the end/destination value and add/subtract from it when creating our tweens.
        private var _minScrollX:Number; //we know the maximum x value for _thumbnailsContainer is 0, but the mimimum value will depend on how many thumbnail images it contains (the total width). We calculate it in the _setupThumbnails() method and store it here for easier/faster scrolling calculations in the _enterFrameHandler()

       

        public function SlideshowExample() {
         super();
       
         //activate the plugins that we'll be using so that TweenLite can tween special properties like filters, colorTransform, and do autoAlpha fades.
         TweenPlugin.activate([AutoAlphaPlugin, ColorTransformPlugin, GlowFilterPlugin]);
       
         _progressBar = this.getChildByName("progress_mc") as MovieClip;
         _arrowLeft = this.getChildByName("arrowLeft_mc") as MovieClip;
         _arrowRight = this.getChildByName("arrowRight_mc") as MovieClip;
       
         _arrowLeft.visible = _arrowRight.visible = false;
         _imagesContainer = new Sprite();
         this.addChildAt(_imagesContainer, 0);
       
         _thumbnailsContainer = new Sprite();
         addChild(_thumbnailsContainer);
         _thumbnailsContainer.y = _IMAGE_HEIGHT;
         _thumbnailsContainer.alpha = 0; //we want alpha 0 initially because we'll fade it in later when the thumbnails load.
         _thumbnailsContainer.visible = false; //ensures nothing is clickable.
       
         var xmlLoader:XMLLoader = new XMLLoader("assets/data.xml", {onComplete:_xmlCompleteHandler});
         xmlLoader.load();
        }

       

        private function _xmlCompleteHandler(event:LoaderEvent):void {
         _slides = [];
         var xml:XML = event.target.content; //the XMLLoader's "content" is the XML that was loaded.
         var imageList:XMLList = xml.image; //In the XML, we have <image /> nodes with all the info we need.
         //loop through each <image /> node and create a Slide object for each.
         for each (var image:XML in imageList) {
          _slides.push( new Slide(image.@name,
                image.@description,
                new ImageLoader("assets/thumbnails/" + image.@name + ".jpg", {name:image.@name + "Thumb", width:_THUMB_WIDTH, height:_THUMB_HEIGHT, scaleMode:"proportionalInside", bgColor:0x000000, estimatedBytes:13000, onFail:_imageFailHandler}),
                new ImageLoader("assets/images/" + image.@name + ".jpg", {name:image.@name + "Image", width:_IMAGE_WIDTH, height:_IMAGE_HEIGHT, scaleMode:"proportionalInside", bgColor:0x000000, estimatedBytes:820000, onFail:_imageFailHandler})
                )
             );
         }
       
         //now create a LoaderMax queue and populate it with all the thumbnail ImageLoaders as well as the very first full-size ImageLoader. We don't want to show anything until the thumbnails are done loading as well as the first full-size one. After that, we'll create another LoaderMax queue containing the rest of the full-size images that will load silently in the background.
         var initialLoadQueue:LoaderMax = new LoaderMax({onComplete:_initialLoadComplete, onProgress:_progressHandler});
         for (var i:int = 0; i < _slides.length; i++) {
          initialLoadQueue.append( _slides[i].thumbnailLoader );
         }
         initialLoadQueue.append(_slides[0].imageLoader); //make sure the very first full-sized image is loaded initially too.
         initialLoadQueue.load();
       
         _setupThumbnails();
        }

       

        private function _initialLoadComplete(event:LoaderEvent):void {
         //now that the initial load is complete, fade out the progressBar. autoAlpha will automatically set visible to false once alpha hits 0.
         TweenLite.to(_progressBar, 0.5, {autoAlpha:0});
         //fade in the thumbnails container
         TweenLite.to(_thumbnailsContainer, 1, {autoAlpha:1});
         _setupArrows();
         //setup the ENTER_FRAME listeners that controls the thumbnail scrolling behavior at the bottom
         this.stage.addEventListener(Event.ENTER_FRAME, _enterFrameHandler, false, 0, true);
       
         //now put all the remaining images into a LoaderMax queue that will load them one-at-a-time in the background in the proper order. This can greatly improve the user's experience compared to loading them on demand which forces the user to wait while the next image loads.
         var imagesQueue:LoaderMax = new LoaderMax({maxConnections:1});
         for (var i:int = 1; i < _slides.length; i++) {
          imagesQueue.append( _slides[i].imageLoader );
         }
         imagesQueue.load();
       
         //now start the slideshow
         _showNext(null);
        }

       

        //loops through all the thumbnail images and places them in the proper order across the bottom of the screen and adds CLICK_THUMBNAIL listeners.
        private function _setupThumbnails():void { 
         var l:int = _slides.length;
         var curX:Number = _THUMB_GAP;
         for (var i:int = 0; i < l; i++) {
          var thumbnail:Sprite = _slides[i].thumbnail;
          _thumbnailsContainer.addChild(thumbnail);
          TweenLite.to(thumbnail, 0, {colorTransform:{brightness:0.5}});
          _slides[i].addEventListener(Slide.CLICK_THUMBNAIL, _clickThumbnailHandler, false, 0, true);
          thumbnail.x = curX;
          thumbnail.y = 4;
          curX += _THUMB_WIDTH + _THUMB_GAP;
         }
         _minScrollX = _IMAGE_WIDTH - curX;
         if (_minScrollX > 0) {
          _minScrollX = 0;
         }
        }

       

        private function _setupArrows():void {
         _arrowLeft.alpha = _arrowRight.alpha = 0;
         _arrowLeft.visible = _arrowRight.visible = true;
         _arrowLeft.addEventListener(MouseEvent.ROLL_OVER, _rollOverArrowHandler, false, 0, true);
         _arrowLeft.addEventListener(MouseEvent.ROLL_OUT, _rollOutArrowHandler, false, 0, true);
         _arrowLeft.addEventListener(MouseEvent.CLICK, _showPrevious, false, 0, true);
         _arrowRight.addEventListener(MouseEvent.ROLL_OVER, _rollOverArrowHandler, false, 0, true);
         _arrowRight.addEventListener(MouseEvent.ROLL_OUT, _rollOutArrowHandler, false, 0, true);
         _arrowRight.addEventListener(MouseEvent.CLICK, _showNext, false, 0, true);
        }

       

        private function _showNext(event:Event=null):void {
         //if there's a _loadingSlide we should assume that the next Slide would be AFTER that one. Otherwise just get the one after the _curSlide.
         var next:int = (_loadingSlide != null) ? _slides.indexOf(_loadingSlide) + 1 : _slides.indexOf(_curSlide) + 1;
         if (next >= _slides.length) {
          next = 0;
         }
         _requestSlide(_slides[next]);
        }

       

        private function _showPrevious(event:Event=null):void {
         //if there's a _loadingSlide we should assume that the previous Slide would be BEFORE that one. Otherwise just get the one before the _curSlide.
         var prev:int = (_loadingSlide != null) ? _slides.indexOf(_loadingSlide) - 1 : _slides.indexOf(_curSlide) - 1;
         if (prev < 0) {
          prev = _slides.length - 1;
         }
         _requestSlide(_slides[prev]);
        }

       

        private function _requestSlide(slide:Slide):void {
         if (slide == _curSlide) {
          return;
         }
         //kill the delayed calls to _showNext so that we start over again with a 5-second wait time.
         TweenLite.killTweensOf(_showNext);
         if (_loadingSlide != null) {
          _cancelPrioritizedSlide(); //the user must have skipped to another Slide and didn't want to wait for the one that was loading.
         }
         //if the requested Slide's full-sized image hasn't loaded yet, we need to show the progress bar and wait for it to load.
         if (slide.imageLoader.progress != 1) {
          _prioritizeSlide(slide);
          return;
         }
         //fade the old Slide and make sure it's not highlighted anymore as the current Slide.
         if (_curSlide != null) {
          TweenLite.to(_curSlide.image, 0.5, {autoAlpha:0});
          _curSlide.setShowingStatus(false);
         }
         _curSlide = slide;
         _imagesContainer.addChild(_curSlide.image); //ensures the image is at the top of the stacking order inside the _imagesContainer
         TweenLite.to(_curSlide.image, 0.5, {autoAlpha:1}); //fade the image in and make sure visible is true.
         _curSlide.setShowingStatus(true); //adds an outline to the image indicating that it's the currently showing Slide.
         TweenLite.delayedCall(5, _showNext); //create a delayedCall that will call _showNext in 5 seconds.
        }

       

        private function _prioritizeSlide(slide:Slide):void {
         TweenLite.to(_progressBar, 0.5, {autoAlpha:1}); //show the progress bar
         _loadingSlide = slide;
         _loadingSlide.imageLoader.addEventListener(LoaderEvent.PROGRESS, _progressHandler);
         _loadingSlide.imageLoader.addEventListener(LoaderEvent.COMPLETE, _completePrioritizedHandler);
         _loadingSlide.imageLoader.prioritize(true); //when the loader is prioritized, it will jump to the top of any LoaderMax queues that it belongs to, so if another loader is in the process of loading in that queue, it will be canceled and this new one will take over which maximizes bandwidth utilization. Once the _loadingSlide is done loading, the LoaderMax queue(s) will continue loading the rest of their images normally.
        }

       

        private function _cancelPrioritizedSlide():void {
         TweenLite.to(_progressBar, 0.5, {autoAlpha:0}); //hide the progress bar
         _loadingSlide.imageLoader.removeEventListener(LoaderEvent.PROGRESS, _progressHandler);
         _loadingSlide.imageLoader.removeEventListener(LoaderEvent.COMPLETE, _completePrioritizedHandler);
         _loadingSlide = null;
        }

       

        private function _completePrioritizedHandler(event:LoaderEvent):void {
         var next:Slide = _loadingSlide; //store it in a local variable first because _cancelPrioritizedSlide() will set _loadingSlide to null.
         _cancelPrioritizedSlide();
         _requestSlide(next);
        }

       

        private function _progressHandler(event:LoaderEvent):void {
         _progressBar.progressBar_mc.scaleX = event.target.progress;
        }

       

        private function _clickThumbnailHandler(event:Event):void {
         _requestSlide(event.target as Slide);
        }

       

        private function _rollOverArrowHandler(event:Event):void {
         TweenLite.to(event.currentTarget, 0.5, {alpha:1});
        }

       

        private function _rollOutArrowHandler(event:Event):void {
         TweenLite.to(event.currentTarget, 0.5, {alpha:0});
        }

       

        private function _enterFrameHandler(event:Event):void {
         if (_thumbnailsContainer.hitTestPoint(this.stage.mouseX, this.stage.mouseY, false)) {
          if (this.mouseX < _SCROLL_AREA) {
           _destScrollX += ((_SCROLL_AREA - this.mouseX) / _SCROLL_AREA) * _SCROLL_SPEED;
           if (_destScrollX > 0) {
            _destScrollX = 0;
           }
           TweenLite.to(_thumbnailsContainer, 0.5, {x:_destScrollX});
          } else if (this.mouseX > _IMAGE_WIDTH - _SCROLL_AREA) {
           _destScrollX -= ((this.mouseX - (_IMAGE_WIDTH - _SCROLL_AREA)) / _SCROLL_AREA) * _SCROLL_SPEED;
           if (_destScrollX < _minScrollX) {
            _destScrollX = _minScrollX;
           }
           TweenLite.to(_thumbnailsContainer, 0.5, {x:_destScrollX});
          }
         }
        }

       

        //if an image fails to load properly, remove it from the slideshow completely including its thumbnail at the bottom.
        private function _imageFailHandler(event:LoaderEvent):void {
         var slide:Slide;
         var i:int = _slides.length;
         while (--i > -1) {
          slide = _slides[i];
          if (event.target == slide.thumbnailLoader || event.target == slide.imageLoader) {
           slide.dispose();
           _slides.splice(i, 1);
           _setupThumbnails();
           return;
          }
         }
        }

       

      }
      }
      [/CODE]

       

      I could figure out that I have to change the line
      [CODE]
      new ImageLoader("assets/images/" + image.@name + ".jpg", {name:image.@name + "Image", width:_IMAGE_WIDTH, height:_IMAGE_HEIGHT, scaleMode:"proportionalInside", bgColor:0x000000, estimatedBytes:820000, onFail:_imageFailHandler}
      [/CODE]
      and instead of ".jpg" put ".swf" (making sure that the names of the files are identical except for their extensions)
      The problem is that I get an error message in the output that flash could not convert my swf file to the bitmap.
      I suspect that I have to change the hard coding to specify that Loader Max should treat loading bigger swf files as swf and not as image/jpg files.
      I don't have enough expertise to decipher all the lines where this has to be changed.
      It feels that I am close to accomplishing what I need. Is it possible to point out where this change has to take place?

       

      Here is my thought process:

      I don't need to specify SWFLoader as LoaderMax is already specified (line 5)

      I don't need to change anything in lines 31-34 as "Sprite" and "Slide" could be an .swf file (line31-34)

      I don't need to change anything in line 50 for the same reason (line 50)

      I don't need to change lines 66 and 68 as image list may contain swf files (line 66 and 68)

      I do need to change ".jpg" to ".swf" in line 72 (line 72)

      No sure if there are any changes in line 82 (line 82)

      LoaderMax has var as imagesQueue does that need to be changed into SFWLoader? (lines98-102)

      I don't think anything need to be changed in lines 138-173 as " Slide" can incorporate an SWF file (lines 138-173)

      Not sure if there has to be a change in lines 175-177 as it specifies that slide is an image (lines 175-177)

      Not sure if there has to be a change in lines 182-200 from imageLoager to SWFLoader (lines 182-200)

      Not sure if there has to be a change in lines 239-245 in specifying SWFLoader (lines 239-245)

       

      I am attaching the .xml and .as documents as well

        • 1. Re: How to specify SWF instead of an image in loading
          kglad CommunityMVP

          assuming your xml is correct, change .jpg in the bold below to .swf:

           

            private function _xmlCompleteHandler(event:LoaderEvent):void {

             _slides = [];

             var xml:XML = event.target.content; //the XMLLoader's "content" is the XML that was loaded.

             var imageList:XMLList = xml.image; //In the XML, we have <image /> nodes with all the info we need.

             //loop through each <image /> node and create a Slide object for each.

             for each (var image:XML in imageList) {

              _slides.push( new Slide(image.@name,

                    image.@description,

                    new ImageLoader("assets/thumbnails/" + image.@name + ".jpg", {name:image.@name + "Thumb", width:_THUMB_WIDTH, height:_THUMB_HEIGHT, scaleMode:"proportionalInside", bgColor:0x000000, estimatedBytes:13000, onFail:_imageFailHandler}),

                    new ImageLoader("assets/images/" + image.@name + ".jpg", {name:image.@name + "Image", width:_IMAGE_WIDTH, height:_IMAGE_HEIGHT, scaleMode:"proportionalInside", bgColor:0x000000, estimatedBytes:820000, onFail:_imageFailHandler})

                    )

                 );

             }

          • 2. Re: How to specify SWF instead of an image in loading
            nikolaig Community Member

            This was my very first step.

            The problem is that I get an error message in the output that flash could not convert my swf file to the bitmap.

            I suspect that I have to change the hard coding to specify that Loader Max should treat loading bigger swf files as swf and not as image/jpg files.

            I don't have enough expertise to decipher all the lines where this has to be changed.

            It feels that I am close to accomplishing what I need. Is it possible to point out where this change has to take place?

             

             

            Just in case here is my xml code:

             

            <?xml version="1.0" encoding="iso-8859-1"?>

            <data>

                      <image name="agencynet" description="agencynet description text goes here." />

                      <image name="buick" description="buick description text goes here." />

                      <image name="cocacola" description="cocacola description text goes here." />

                      <image name="cu3er" description="cu3er description text goes here." />

                      <image name="diva" description="diva description text goes here." />

                      <image name="dow" description="dow description text goes here." />

                      <image name="erkyperky" description="erkyperky description text goes here." />

                      <image name="flexa" description="flexa description text goes here." />

                      <image name="happyplanetshots" description="happyplanetshots description text goes here." />

                      <image name="holdencruze" description="holdencruze description text goes here." />

                      <image name="ironman" description="ironman description text goes here." />

                      <image name="mercedes" description="mercedes description text goes here." />

                      <image name="micromaniac" description="micromaniac description text goes here." />

                      <image name="overtheatlantic" description="overtheatlantic description text goes here." />

                      <image name="saab" description="saab description text goes here." />

                      <image name="silverpistol" description="silverpistol description text goes here." />

                      <image name="softse" description="softse description text goes here." />

                      <image name="target" description="target description text goes here." />

                      <image name="tonydorio" description="tonydorio description text goes here." />

                      <image name="prius" description="prius description text goes here." />

                      <image name="waterlife" description="waterlife description text goes here." />

            </data>

            • 3. Re: How to specify SWF instead of an image in loading
              kglad CommunityMVP

              the problem is probably in loadermax.  you'll need to edit that code or use the loader class instead of gs' loadermax

              • 4. Re: How to specify SWF instead of an image in loading
                nikolaig Community Member

                I can not figure out where to edit the code in LoaderMax, Is it possible to point out or give a hint which specs have to be replaced?

                In my first post I tried to be very spedific and analyzed the code line by line (so the those who answer me will not have to do it) where I suspected the change has to take place.

                If feasable please take a look

                • 5. Re: How to specify SWF instead of an image in loading
                  kglad CommunityMVP

                  i've never used loadermax so i could not tell you that.  but i can tell you that you will need to search for ".load("

                   

                  when you find that look at the loader's name to which that is applied, check for a complete listener and in there you'll find he's casting the loader's content as a bitmap.  you'll need to add something like:

                   

                  if(whateveloadername_or_eventtarget.content is Bitmap){

                  // cast as bitmap code here

                  }