Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
attaboy

trying to use loaderMax with a slideshow

Recommended Posts

I'm very new to everything greensock. I built a slideshow with a greensock tween the tween is way cool. You can see the slideshow by going here:

http://www.droolpigs.com/ and clicking the About Us button. The slideshow is fine except that every now and then a slide doesn't align. I was told that I might be able to fix the problem by using loaderMax.

this is my original code:

		import com.greensock.*;
		import com.greensock.easing.*;
	import flash.display.*;
	import flash.utils.*;
	import flash.events.*;
	import flash.net.*;
	import flash.text.*;

	var myFont:Font3 = new Font3();
	var extReq:URLRequest = new URLRequest("bio.txt");
	var extLoader:URLLoader = new URLLoader();
	var myFormat:TextFormat = new TextFormat();
///		
	var tf:TextField = new TextField();
	var tf3:TextField = new TextField();
	var msk:Sprite = new Sprite();
	var tl:TimelineMax = new TimelineMax({repeat:-1});	
///
//		var bio:Bio = new Bio();
		var bars:Bars = new Bars();
	var n:int = 0;
	var intCurrentSlide:int;
	var req:URLRequest; 
  		var holder:Sprite = new Sprite();
//		var holderBG:HolderBG = new HolderBG();
	var loader:Loader;
	var rand:int;
	var nxtNum:int;
	var picNum:String;
	var slideCount:int;
	var xmlLoader:URLLoader;   // slideshow xml loader
	var xmlSlideshow:XML;  // slideshow xml
	var strXMLPath:String = "bioPics-data.xml";
	var slideName:String;
      var history:Array = new Array();
		var duration:Number=.5;
	var prevSlide:String;
	var timeline:TimelineMax;
//////////		

	xmlLoader = new URLLoader();   
	xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete);
	xmlLoader.load(new URLRequest(strXMLPath));

///////////// text setup ////////////////////
tf.x =-285;
//tf.y =655;
tf.y=700;
tf.width = 700;
tf.height = 800;
tf.multiline=true;
tf.wordWrap=true;
tf.condenseWhite=true;

//tf2

tf3.x =-285;
tf3.y =660;
tf3.width = 700;
tf3.height = 20;
tf3.htmlText = 'Contact links and Email:      droolpigs.com | myspace site      droolpigs@gmail.com | invisibleblindman@hotmail.com';

addChild(tf);
addChild(tf3);


msk.graphics.beginFill(0x000000);
msk.graphics.drawRect(0, 0, 700, 165);
msk.x = -285;
msk.y = 485;
msk.graphics.endFill();

extLoader.addEventListener(Event.COMPLETE, textReady);

myFormat.font = myFont.fontName;
myFormat.color = "0xffaa00";
//0x77ffaa


myFormat.size = 18;
myFormat.leading = 2.5;

tf.defaultTextFormat=myFormat;
tf.embedFonts=true;
tf.alpha=1;

extLoader.load(extReq);

function textReady(e:Event):void {
tf.cacheAsBitmap=true;
	msk.cacheAsBitmap=true;
tf.mask=msk;
addChild(msk);
tf.htmlText=e.target.data;
}

tl.insert( new TweenLite(tf, 70, {y:"-940", ease:Linear.easeNone}) );
//////////////text setup////////////////////////	

		createTimeline();

	function onXMLLoadComplete(e:Event):void {
			xmlLoader.removeEventListener(Event.COMPLETE, onXMLLoadComplete);
			xmlSlideshow = new XML(e.target.data);     // create new xml with the received data
			slideCount = xmlSlideshow..image.length();   // get total slide count
			loadSlide();
	}


		function loadSlide():void {
 			prevSlide=history[history.length-1];
		rand = Math.ceil(Math.random()* slideCount - 1);  
			loader = new Loader();
			req = new URLRequest(xmlSlideshow..@src[rand]);
			loader.contentLoaderInfo.addEventListener(Event.INIT, displaySlide);
			loader.load(req);
		slideName = xmlSlideshow..@src[rand].toString();

	if(slideName != prevSlide){
				history.push(slideName); 
			loader.load(new URLRequest(xmlSlideshow..@src[rand]));

		}else{
			loadSlide();
			}
	}

     	function createTimeline():void{
       timeline =new TimelineMax({repeat:1,repeatDelay:5,yoyo:true,onComplete:loadSlide, paused:true});
       for (var count:int = 1; count <=10; count++) {
           var mc:MovieClip=bars["bar"+count];
           timeline.append(TweenMax.from(mc, duration, {x:"64", alpha:0, ease:Cubic.easeOut}), -.4);
        	}
       }

	function displaySlide(e:Event = null):void {
		loader.contentLoaderInfo.removeEventListener(Event.INIT, displaySlide);
		if (holderBG.holder)
		{
		holderBG.removeChild(holder);
		holderBG.holder = null;
		}
//			trace ("holder.numChildren "+holder.numChildren);
			if(holder.numChildren > 0){holder.removeChildAt(0);}
 			holder.addChild(loader.content);

		// center the pic
		holder.x=holderBG.width/2 - holder.width/2;
		holder.y=holderBG.height/2 - holder.height/2;
		// make the mask position over the pic
		 bars.x=holder.x;
		 bars.y=holder.y;
			 bars.cacheAsBitmap=true;
 			holder.cacheAsBitmap=true;
			holder.mask=bars;
		 bars.width = holder.width;
			 bars.height = holder.height;
		 holderBG.addChild(holder);
			 holderBG.addChild(bars);
		timeline.restart();		}

and this is my feeble attempt to load the slides with loaderMax .

 

import com.greensock.*;

import com.greensock.easing.*;

import com.greensock.loading.ImageLoader;

import flash.display.*;

import flash.utils.*;

import flash.events.*;

import flash.net.*;

import flash.text.*;

 

var myFont:Font3 = new Font3();

var extReq:URLRequest = new URLRequest("bio.txt");

var extLoader:URLLoader = new URLLoader();

var myFormat:TextFormat = new TextFormat();

 

var bars:Bars = new Bars();

var n:int = 0;

var intCurrentSlide:int;

var req:URLRequest;

var holder:Sprite = new Sprite();

// var holderBG:HolderBG = new HolderBG();

var loader:Loader;

var rand:int;

var nxtNum:int;

var picNum:String;

var slideCount:int;

var xmlLoader:URLLoader; // slideshow xml loader

var xmlSlideshow:XML; // slideshow xml

var strXMLPath:String = "bioPics-data.xml";

var slideName:String;

var history:Array = new Array();

var duration:Number=.5;

var prevSlide:String;

var timeline:TimelineMax;

//////////

xmlLoader = new URLLoader();

xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete);

xmlLoader.load(new URLRequest(strXMLPath));

 

 

createTimeline();

 

function onXMLLoadComplete(e:Event):void {

xmlLoader.removeEventListener(Event.COMPLETE, onXMLLoadComplete);

xmlSlideshow = new XML(e.target.data); // create new xml with the received data

slideCount = xmlSlideshow..image.length(); // get total slide count

loadSlide();

}

 

 

function loadSlide():void {

prevSlide=history[history.length-1];

rand = Math.ceil(Math.random()* slideCount - 1);

var image:ImageLoader = new ImageLoader(xmlSlideshow..@src[rand],

{container:this,

x:275, y:240,

width:600, height:300,

scaleMode:"proportionalInside",

centerRegistration:true,

// blendMode:"overlay",

bgColor:0x000000,

rotation:0});

 

image.load();

holderBG.addChild(image);

holderBG.addChild(bars);

 

// bars.x=image.container.x;

// bars.y=image.container.y;

// bars.cacheAsBitmap=true;

// image.cacheAsBitmap=true;

// image.mask=bars;

// bars.width = image.width;

// bars.height = image.height;

 

timeline.restart();

 

 

 

}

 

function createTimeline():void{

timeline =new TimelineMax({repeat:1,repeatDelay:5,yoyo:true,onComplete:loadSlide, paused:true});

for (var count:int = 1; count <=10; count++) {

var mc:MovieClip=bars["bar"+count];

timeline.append(TweenMax.from(mc, duration, {x:"64", alpha:0, ease:Cubic.easeOut}), -.4);

}

}

 

Apparently I can't treat the loaderMax instance as a display object and I don't know how to put the tween inside loaderMax.

Link to comment
Share on other sites

It's very tough to work with the raw code without seeing it in context (you reference a bunch of stuff that's on the stage or in the library I assume). I'm taking a stab in the dark here and I'm sure you'll need to tweak some things, but here's a very quick stab:

 

import com.greensock.*;
import com.greensock.easing.*;
import flash.display.*;
import flash.utils.*;
import flash.events.*;
import flash.net.*;
import flash.text.*;
import com.greensock.loading.*;
import flash.geom.Rectangle;

var myFont:Font3 = new Font3();
var myFormat:TextFormat = new TextFormat();
///      
var tf:TextField = new TextField();
var tf3:TextField = new TextField();
var msk:Sprite = new Sprite();
var tl:TimelineMax = new TimelineMax({repeat:-1});
///
//      var bio:Bio = new Bio();
var bars:Bars = new Bars();
var n:int = 0;
var intCurrentSlide:int;
var req:URLRequest;
var holder:Sprite = new Sprite();
//      var holderBG:HolderBG = new HolderBG();
var loader:ImageLoader;
var rand:int;
var nxtNum:int;
var picNum:String;
var slideCount:int;
var xmlSlideshow:XML;// slideshow xml
var slideName:String;
var history:Array = new Array();
var duration:Number = .5;
var prevSlide:String;
var timeline:TimelineMax;

//center holder's x/y
holder.x = holderBG.x + holderBG.width / 2;
holder.y = holderBG.y + holderBG.height / 2;
//////////      

var xmlLoader:XMLLoader = new XMLLoader("bioPics-data.xml", {onComplete:onXMLLoadComplete});
xmlLoader.load();

///////////// text setup ////////////////////
tf.x = -285;
//tf.y =655;
tf.y = 700;
tf.width = 700;
tf.height = 800;
tf.multiline = true;
tf.wordWrap = true;
tf.condenseWhite = true;

tf3.x = -285;
tf3.y = 660;
tf3.width = 700;
tf3.height = 20;
tf3.htmlText = 'Contact links and Email:      droolpigs.com | myspace site      droolpigs@gmail.com | invisibleblindman@hotmail.com';

addChild(tf);
addChild(tf3);

msk.graphics.beginFill(0x000000);
msk.graphics.drawRect(0, 0, 700, 165);
msk.x = -285;
msk.y = 485;
msk.graphics.endFill();

var extLoader:DataLoader = new DataLoader("bio.txt", {onComplete:textReady});
extLoader.load();

myFormat.font = myFont.fontName;
myFormat.color = "0xffaa00";

myFormat.size = 18;
myFormat.leading = 2.5;

tf.defaultTextFormat = myFormat;
tf.embedFonts = true;
tf.alpha = 1;

function textReady(e:Event):void {
tf.cacheAsBitmap = true;
msk.cacheAsBitmap = true;
tf.mask = msk;
addChild(msk);
tf.htmlText = e.target.data;
}

tl.insert( new TweenLite(tf, 70, {y:"-940", ease:Linear.easeNone}) );
//////////////text setup////////////////////////   
createTimeline();

function onXMLLoadComplete(e:Event):void {
xmlSlideshow = xmlLoader.content;
slideCount = xmlSlideshow..image.length();// get total slide count
loadSlide();
}


function loadSlide():void {
prevSlide = history[history.length - 1];
rand = int(Math.random() * slideCount);
slideName = xmlSlideshow..@src[rand];

if (slideName != prevSlide) {
	history.push(slideName);
	loader = new ImageLoader(slideName, {onInit:displaySlide, centerRegistration:true, container:holder});
	loader.load();

} else {
	loadSlide();
}
}

function createTimeline():void {
timeline = new TimelineMax({repeat:1, repeatDelay:5, yoyo:true, onComplete:loadSlide, paused:true});
for (var count:int = 1; count 		var mc:MovieClip = bars["bar" + count];
	timeline.append(TweenMax.from(mc, duration, {x:"64", alpha:0, ease:Cubic.easeOut}), -.4);
}
}

function displaySlide(e:Event = null):void {
if (holderBG.holder) {
	holderBG.removeChild(holder);
	holderBG.holder = null;
}
//         trace ("holder.numChildren "+holder.numChildren);
if (holder.numChildren > 1) {
	holder.removeChildAt(0);
}

// make the mask position over the pic
var bounds:Rectangle = holder.getBounds(holder.parent);
bars.x = bounds.x;
bars.y = bounds.y;
bars.cacheAsBitmap = true;
holder.cacheAsBitmap = true;
holder.mask = bars;
bars.width = holder.width;
bars.height = holder.height;
holderBG.addChild(holder);
holderBG.addChild(bars);
timeline.restart();
}

 

I would definitely structure things differently if I were building this from scratch, but I didn't want to alter your code too much. Basically, you can create an ImageLoader anytime you want to load an image and you can tell that ImageLoader to center the registration, set a width/height, etc. It's all in the ASDocs and in the various tutorials online. If you haven't watched the videos at

Link to comment
Share on other sites

Thanks for the help I think we're getting close. I removed some extraneous code and tried to implement your changes.

Here's what I have now:

 

//// this is timeline code within a MovieClip////

import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.loading.*;
import flash.display.*;
import flash.utils.*;
import flash.events.*;
import flash.net.*;
import flash.text.*;
import flash.geom.*;

var bars:Bars = new Bars();
var n:int = 0;
var intCurrentSlide:int;
var req:URLRequest; 
var holder:Sprite = new Sprite();
var loader:ImageLoader;
var rand:int;
var nxtNum:int;
var picNum:String;
var slideCount:int;
var xmlLoader:URLLoader;   // slideshow xml loader
var xmlSlideshow:XML;  // slideshow xml
var strXMLPath:String = "bioPics-data.xml";
var slideName:String;
var duration:Number=.5;
var prevSlide:String;
var timeline:TimelineMax;

createTimeline();

xmlLoader = new URLLoader();   
xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete);
xmlLoader.load(new URLRequest(strXMLPath));

function onXMLLoadComplete(e:Event):void {
	xmlLoader.removeEventListener(Event.COMPLETE, onXMLLoadComplete);
	xmlSlideshow = new XML(e.target.data);     // create new xml with the received data
	slideCount = xmlSlideshow..image.length();   // get total slide count
	loadSlide();
}

function createTimeline():void{
timeline =new TimelineMax({repeat:1,repeatDelay:5,yoyo:true,onComplete:loadSlide, paused:true});
for (var count:int = 1; count <=10; count++) {
	var mc:MovieClip=bars["bar"+count];
	timeline.append(TweenMax.from(mc, duration, {x:"64", alpha:0, ease:Cubic.easeOut}), -.4);
	}
}

function loadSlide():void {
	rand = Math.ceil(Math.random()* slideCount - 1);
[b]		loader = new ImageLoader(slideName, {onInit:displaySlide, centerRegistration:true, container:holder});			
	// the assignment of loader seems to be where I'm getting hung up this is the line 54 in error msg.[/b]
	loader.load();
}

function displaySlide(e:Event):void {
	trace("in displaySlide");
   var bounds:Rectangle = holder.getBounds(holder.parent);
   bars.x = bounds.x;  //bars is a MC in the library
   bars.y = bounds.y;
   bars.cacheAsBitmap = true;
   holder.cacheAsBitmap = true;
   holder.mask = bars;
   bars.width = holder.width;
   bars.height = holder.height;
   holderBG.addChild(holder);  //holderBG is a MC that's placed on stage at author time
   holderBG.addChild(bars);
   timeline.restart();
   }

 

When I run it I get this error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.

at com.greensock.loading.core::LoaderItem/_setRequestURL()[C]

at com.greensock.loading.core::LoaderItem()[C]

at com.greensock.loading.core::DisplayObjectLoader()[C]

at com.greensock.loading::ImageLoader()[C]

at Bio2/loadSlide()[bio2]

at Bio2/onXMLLoadComplete()[bio2]

at flash.events::EventDispatcher/dispatchEventFunction()

at flash.events::EventDispatcher/dispatchEvent()

at flash.net::URLLoader/onComplete()

Link to comment
Share on other sites

It's very difficult to troubleshoot without seeing the code in context and being able to publish the file, but it looks to me like either slideName is null or holder is null in your ImageLoader() constructor.

Link to comment
Share on other sites

Closer still we've got everything working except the transition tween...see attachment

Link to comment
Share on other sites

Well, there were quite a few problems I saw. So many that instead of explaining them all, I figured I'd just rewrite most of the code for you. Here are a few highlights:

 

1) It's wasteful to load the same image more than once (well, unless you're loading hundreds or thousands of them and can't afford the memory). I altered your code so that it creates a LoaderMax queue of all the images, loads the first one and displays it, then loads all the rest in the background so that performance is super-snappy when the next image is needed. No need to wait for it to load again.

 

2) You were grabbing a random image from the array, but the down side of doing this is that you can end up displaying the same image twice in a row. Or repeat the same image too soon (like image1, image2, image1). So I created a separate array that basically serves as a queue and when an image is randomly chosen from it, it gets removed from the array. Once the array is empty, it refills itself with all the original images. That way you get a random effect, but you also get a nice varied selection along the way.

 

3) In order to simplify things, I changed your "bars" MovieClip so that its registration point was in its center. That way, you can leave the x/y at 0/0 and when you change the width/height, it automatically lines up with everything.

 

Here's the revised code:

import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.loading.*;
import flash.display.*;
import flash.geom.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.display.ContentDisplay;

var duration:Number = .5;
var timeline:TimelineMax;
var bars:Bars = new Bars();
bars.cacheAsBitmap = true;
holderBG.addChild(bars);

createTimeline();

function createTimeline():void {
timeline = new TimelineMax({repeat:1, repeatDelay:5, yoyo:true, onComplete:showRandom, paused:true});
for (var count:int = 1; count 		var mc:MovieClip = bars["bar" + count];
	timeline.insert(TweenMax.from(mc, duration, {x:"64", alpha:0, ease:Cubic.easeOut}), (count - 1) * 0.1);
}
}

var xmlLoader:XMLLoader = new XMLLoader("bioPics-data.xml", {onComplete:onXMLLoadComplete, autoDispose:true});;
xmlLoader.load();
var images:Array;
var displayQueue:Array; //same as "images" array initially, but each time we show a random image, we remove it from this array so that we can make sure the same image never shows twice in a row. We repopulate the array by slicing the images array once displayQueue is empty.
var curSlide:ContentDisplay;

function onXMLLoadComplete(e:Event):void {
var queue:LoaderMax = new LoaderMax({maxConnections:1});
var nativeHolderSize:Rectangle = holderBG.getBounds(holderBG);
for each (var image:XML in xmlLoader.content.image) {
	queue.append( new ImageLoader(image.@src, {centerRegistration:true, width:nativeHolderSize.width, height:nativeHolderSize.height, scaleMode:"proportionalInside"}) );
}
images = queue.content; //a LoaderMax's "content" is an array of all of its child loaders' content. In this case, a bunch of ContentDisplay objects.
displayQueue = images.slice();

//choose a random image to load first...
var randomIndex:int = int(Math.random() * displayQueue.length);
displayQueue[randomIndex].loader.prioritize(false); //ensures that it is first in the loading queue
displayQueue[randomIndex].loader.addEventListener(LoaderEvent.COMPLETE, startSlideshow, false, 0, true); //we just want to wait for the first one to load before beginning. The rest can load in the background.
displayQueue.splice(randomIndex, 1);

queue.load();
}

function startSlideshow(event:LoaderEvent):void {
displaySlide(event.target.content);
}

function showRandom():void {
if (displayQueue.length == 0) {
	displayQueue = images.slice();
}
var randomIndex:int = int(Math.random() * displayQueue.length);
displaySlide( displayQueue[randomIndex] );
displayQueue.splice(randomIndex, 1);
}

function displaySlide(slide:ContentDisplay):void {
if (curSlide != null) {
	holderBG.removeChild(curSlide);
}
curSlide = slide;
holderBG.addChild(slide);
slide.cacheAsBitmap = true;
slide.mask = bars;
bars.width = slide.rawContent.width;
bars.height = slide.rawContent.height;
timeline.restart();
}

 

See attached for the revised FLA.

Link to comment
Share on other sites

WOW! This goes way beyond what I was hoping for. You've showed me a much better way to write slide shows I'll study this code thoroughly and go through some of the gs tutorials as well. Thanks so much.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×