Jump to content
Search Community

Timeline Q

beno test
Moderator Tag

Recommended Posts

Hi;

I have this code:

 

var timeline:TimelineMax = new TimelineMax();

whichPic = 1;

while (whichPic <= 9)

{

timeline.append(TweenLite.to(img_container, .1, {delay:6.5, x:-1006*whichPic}) );

++whichPic;

}

timeline.repeat = -1;

 

Works fine. Has an image pop up, stay there for a bit, then slides over another image. Now what I need to do is determine what the value of whichPic is when_it_is_playing. How do?

TIA,

Beno

Link to comment
Share on other sites

The value of whichPic will only change from 1 to 10 while the while loop is running. the loop will run virtually instantaneously.

After the loop runs, the value of whichPic will be 10 for eternity.

 

The playing of the timeline, or tweens in the timeline will have no effect whatsoever on the value of whichPic.

 

make the following adjustments to your code:

 

var timeline:TimelineMax = new TimelineMax();

whichPic=1;

while (whichPic

timeline.append(TweenLite.to(img_container, .1, {delay:6.5, x:-1006*whichPic}) );

++whichPic;

trace("while " + whichPic);

 

}

timeline.repeat=-1;

 

stage.addEventListener(Event.ENTER_FRAME, whatsWhichPic);

 

function whatsWhichPic(e:Event){

trace("enterFrame " + whichPic);

}

 

you will see the following output:

 

while 2

while 3

while 4

while 5

while 6

while 7

while 8

while 9

while 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

enterFrame 10

...

 

in conclusion, the value of whichPic will always be 10.

 

I have a hunch you may have meant to ask "how do i determine which tween is playing" or something similar. If so, please clarify.

 

Carl

Link to comment
Share on other sites

one way you could do it is like so.

 

import com.greensock.*;
import com.greensock.easing.*;



var tl:TimelineMax = new TimelineMax({repeat:-1});

var tweenCount:int = 0;

while (tweenCount++ 	tl.append(TweenLite.to(mc, 1, {x:tweenCount *50, delay:1, onStart:getTweenCount, onStartParams:[tweenCount]}));
}

tl.play();

function getTweenCount(currentTween:int):void{
trace(currentTween);
//this function could be set to return a value 
//return currentTween
//or set global variable to the value that you need.
//tweenCount = currentTween

}

 

 

don't have time to explain but cs4 fla attached (no greensock classes)

 

you might also use addLabel() when each tween is created and then call tl.getLabelBefore() or something similar

Link to comment
Share on other sites

A few other options:

 

1) Just figure out the value based on the x position of img_container. This would be the most efficient way and it would work if you reverse() the timeline too.

 

2) Figure it out based on the currentTime of the TimelineMax. Again, this approach would work in reverse() too.

 

3) Create a Dictionary lookup and associate the tween with the index number. Then you could use TimelineMax's getActive() method to look things up, like this:

 

var tweenLookup:Dictionary = new Dictionary();
while (whichPic     tweenLookup[ timeline.append(TweenLite.to(img_container, .1, {delay:6.5, x:-1006*whichPic}) ) ] = whichPic;
   ++whichPic;
}

//then use getActive() to find the currently active tween and look up the whichPic value:
var curPic:int = tweenLookup[ timeline.getActive()[0] ];

 

Personally, I think the first two options are cleanest.

Link to comment
Share on other sites

Thanks, Carl. That worked great. I have another related problem, however. Here's my code:

 

var timeline:TimelineMax = new TimelineMax({repeat:-1});

while (tweenCount++ < 9)

{

timeline.append(TweenLite.to(img_container, 1, {x:-1006*tweenCount, delay:6.5, onStart:getTweenCount, onStartParams:[tweenCount]}));

}

timeline.play();

}

 

private function getTweenCount(currentTween:int):void

{

switch (currentTween)

{

case 0:

btn0.ImagesArray = ["images/change-img-btn_on.png", "index.py", 45, 45, 0, 0];

container_btn0.x = 1100;

container_btn0.y = 474;

if (container_btn0.parent)

{

container_btn0.parent.removeChild(container_btn0);

}

addChild(container_btn0);

container_btn0.addChild(btn0);

 

I then repeat most of that code for each of the button images, changing the image button to the *_off.png. In the subsequent cases, I simply move the *_on.png further down. Now here's the problem. When the tween repeats, the value of currentTween is set at the maximum and the last button is set to *_on.png whereas it should be set to the first button. I would have thought simply passing a new value to currentTween in the last case would have done the trick, but no. (I initially set its value to 0 before running the above code.) What do here?

TIA,

Beno

Link to comment
Share on other sites

hi beno

 

i don't really understand the question.

 

what do you mean by "when the tween repeats"? do you mean the timeline? there is a big difference

 

if something special has to happen at the end of the timeline to reset things you could try

 

var timeline:TimelineMax = new TimelineMax({repeat:-1, onComplete:resetStuff}); // or maybe onRepeat:resetStuff

 

function resetStuff(){

//do stuff to make the buttons do the right thing

 

}

 

thinking about it more in your switch statement you should be able to handle what needs to be done in

 

case 0 or case 9

 

i really don't know what the problem is. The initial question was in regards to determining which tween was playing and now there is a lot more functionality involved with switching buttons around. It would probably help if you explained what exactly you were trying to accomplish.

 

perhaps you can post a swf somewhere and describe what should happen and what is happening that is wrong. much easier than trying to decipher code fragments.

 

Carl

Link to comment
Share on other sites

I'm sorry, yes: repeat the timeline. In the code I sent you last, when the timeline repeats, the trace that I just added to case 0 doesn't trace var countTween; therefore, I don't understand what happens internally with greensock's repeat. I would have expected it to re-read the code, but it doesn't appear to do that.

 

Here is the url you requested:

http://creative.vi/clients/Maya2012/index.py

You'll see those little buttons at the bottom. When the last one turns light, the next image to scroll across will be the first (repeating the timeline) and I want the first button to light up, but it doesn't.

TIA,

Beno

Link to comment
Share on other sites

Beno, thanks for the clear explanation.

 

so it seems the root problem is that your case 0 isn't running on repeat of the timeline.

 

if you go back to my original files that I attached, that example repeats and the proper values trace each time the timeline plays.

so there is not anything internally wrong with the greensock files not firing the onStart function or passing in the onStartParams.

 

it is always good to make sure you are using the latest com folder. are you using an old version perhaps.

 

if you want to post a simplified fla file (cs4 or lower) I can try to look at it tonight.

 

you should try to strip down (in a separate file) the timeline to a point where only 1or 2 simple tweens is happening and you can trace tweenCount every time the timeline repeats.

Link to comment
Share on other sites

Hi Beno,

 

as a note it doesn't do much good if you provide files that can't compile because there are missing classes.

 

the problem is tweenCount is never 0

 

the code:

 

var tweenCount:int = 0;
while (tweenCount++ 	{
			trace(tweenCount);
}

 

will output

1

2

3

 

 

possibly the reason things appear to work the first time around is because you have this

 

public function test()

{

BackgroundImages();

getTweenCount(0);

}

 

which forces getTween to run with an argument of 0 (which probably generates your trace) ... but 0 is never generated in your timeline building loop

 

while (tweenCount++ 			{
			timeline.append(TweenLite.to(img_container, 1, {x:-1006*tweenCount, delay:2, onStart:getTweenCount, onStartParams:[tweenCount]}));
		}
		timeline.play();

 

your code is incrementing tweenCount BEFORE the contents of the loop run.

 

you could do

 

var tweenCount:int = 0;

while (tweenCount

{

trace(tweenCount);

tweenCount++

}

will output 0, 1, 2

 

give it a shot

 

also to learn more about the post / pre ++ increment operator check out:

http://livedocs.adobe.com/flash/9.0/Act ... #increment

it helped me quite a bit.

Link to comment
Share on other sites

Sorry about that. Please comment these two lines out of the class I sent you:

 

import Navigate;

import URLClip;

 

Below is the code for the other class you need. I still can't get this working, but as you say, once you see it it should become obvious what the problems are.

TIA,

Beno

 

 

package {

import flash.display.MovieClip;

import flash.display.Sprite;

import flash.display.Bitmap;

import flash.display.BitmapData;

import flash.filters.*;

import flash.filters.BitmapFilterQuality;

import flash.net.URLRequest;

import flash.net.URLLoader;

import flash.display.Loader;

import flash.display.LoaderInfo;

import flash.display.DisplayObject;

import flash.events.Event;

import flash.events.IOErrorEvent;

 

public class Images extends MovieClip

{

private var parent_container:Sprite = new Sprite();

private var _path:String = new String("path");

private var _myWidth:Number = new Number(20);

private var _myHeight:Number = new Number(20);

private var _myX:Number = new Number(20);

private var _myY:Number = new Number(20);

private var _myURL:String = new String("url");

 

public function Images():void

{

}

 

public function set ImagesArray(_imagesArray:Array):void

{

_path = _imagesArray[0];

_myURL = _imagesArray[1];

_myWidth = _imagesArray[2];

_myHeight = _imagesArray[3];

_myX = _imagesArray[4];

_myY = _imagesArray[5];

LoadImage();

}

 

function LoadImage():void

{

parent_container = new Sprite();

addChild(parent_container)

var req:URLRequest = new URLRequest(_path);

var loader:Loader = new Loader();

loader.load(req);

loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadedImage);

}

 

function LoadedImage(e:Event):void

{

var loaderInfo:LoaderInfo = e.target as LoaderInfo;

var displayObject:DisplayObject = loaderInfo.content;

displayObject.width = _myWidth;

displayObject.height = _myHeight;

parent_container.addChild(displayObject);

parent_container.x = _myX;

parent_container.y = _myY;

}

 

function ioErrorHandler(event:IOErrorEvent):void {

trace("ioErrorHandler: " + event);

}

}

}

Link to comment
Share on other sites

replace the first 2 functions in test.as with these:

 

public function test()

{

BackgroundImages();

//getTweenCount(0);

}

 

private function BackgroundImages():void

{

var img_container:Sprite = new Sprite();

for (i; i

{

var img:Images = new Images();

img.ImagesArray = [bkgnd_imgs, "index.py", 1006,523, 0, 0];

img.x = 1006 * i;

img_container.addChild(img);

}

addChild(img_container);

var timeline:TimelineMax = new TimelineMax({repeat:-1});

while (tweenCount

{

timeline.append(TweenLite.to(img_container, 1, {x:-1006*tweenCount, delay:2, onStart:getTweenCount, onStartParams:[tweenCount]}));

tweenCount++

}

timeline.play();

 

}

i made the same changes I suggested previously.

when the timeline repeats, the first button is light blue when the first image is displayed

 

give it try it should work

 

c

Link to comment
Share on other sites

Definitely an improvement, Carl, but notice how on the repeat the first image pops into place where I really need it to gracefully slide into place like the others do. I've messed with this but with the equally unsatisfactory result of showing a black screen for a second. Ideas?

TIA,

Beno

Link to comment
Share on other sites

Hi beno,

 

the code is working exactly as expected.

your timeline starts out with image 1 on stage (it doesn't tween in)

image 2 comes in from the right and pushes 1 off to the left

image 3 comes in from the right and pushes 2 off to the left

 

when you repeat... it jumps back to the beginning with image 1 just sitting there on the stage.

 

 

if you want the first image to tween in from the right as the last image (3) tweens out to the left you have 2 options with your current setup:

 

option 1) create a duplicate of the first image so your sequence will really be 1, 2, 3, 1. When the last image 1 is done tweening... then restart your timeline which will shift everything back to the starting positions

 

option 2) as soon as image 3 is done sliding in (onComplete), reposition image 1 to the right of image 3

while image 3 slides out left also slide in image 1 from the right

when that tween is done, tell the timeline to restart

 

this works fine for a small handful of images. suppose you had 100 images you wanted to tween in such a sequence. It would be very difficult (performance wise) to tween them all at the same time.

The best way to approach this is really to only tween 2 images at a time

1 - the image currently being displayed

2- the next image that needs to be displayed

 

to see this concept in action take a look at this thing I made ages and ages ago with AS2

http://doyouhaveapen.com/junkyart/dynam ... ORIAL.html

 

CLICK the button that says EXPANDED TUTORIAL MODE and follow the instructions. this little tutorial was built to show that you can literally navigate / scroll through thousands of thumbnails / objects by only moving the ones that need to move.

the source file is ancient but the general concepts are quite valid.

 

when I get into situations like this I often try to build my animation on the flash timeline or use a series of post-it notes on my desk so that I can visualize exactly what needs to happen... then I try to communicate what I need to happen with actionscript.

 

The purpose of this forum is to help people understand the workings of the greensock tweening classes.

As much as I enjoy helping, it isn't feasible to offer assistance through multiple phases of project development.

Hopefully the advice given will be sufficient to allow you to chose a course of action for your next step.

 

As always, I suggest starting with a very simple file (without buttons flying around and changing state) that allows you to tween through a series of just 3 images in a seamless loop. Once you get that hammered down you can integrate it into the larger project.

 

Carl

 

EDIT

-since all your images are in 1 container that is being tweened, it will most likely be easiest just to do option1 and add another image 1 after image 3 in the container. you will just need to add 1 more tween to your timeline.

Link to comment
Share on other sites

as a followup to my last suggestion look here

 

http://www.snorkl.tv/dev/fakeLoop/fakeLoop.html

 

this approach is going to be the easiest to implement

 

once your container has a duplicate of the first image at the end, the code for this example is simply

import com.greensock.*;

var tl:TimelineMax = new TimelineMax({repeat:-1, onComplete:reset});

var tweenCount:int = 0;

while (tweenCount 	tl.append(TweenLite.to(container, 1, {x:"-150", delay:.5}));
tweenCount++;
}

function reset(){
trace("complete");
container.x = 500;
}	

 

cs4 fla attached

Link to comment
Share on other sites

Yeah, I know my question went beyond the scope of GS, but since we were on the subject :/

Thanks for the tutorial, Carl! Yeah, I went with option 1 for this project, but have another project I'm working on that tackles the same problem but has a dynamic number of images which can be edited and updated by the client, so that tutorial will come in handy in a few days!

Thanks again,

Beno

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.
×
×
  • Create New...