Jump to content
Search Community

PNG sequence on TimelineLite

patrick.welborn test
Moderator Tag

Recommended Posts

hello.

 

can you please be more specific about exactly what you want to accomplish?

 

"arrange a sequence of pngs which plays" isn't clear to me.

 

do you want multiple images to be animated? are you trying to simulate a keyframed animation?

 

thx

 

Carl

Link to comment
Share on other sites

I want a timeline to display a series of frames in which each frame contains a single static bitmap image. My partially developed methodology sort of does what I want (see below). But it seems like this is not the most efficient way to accomplish my task.

AS3

public function init(data:XMLList):void
{
this.data = data;

for each (var action:XML in data.action)
{
	for each (var sequence:XML in action.*)
	{
		var frameDuration:Number = 1 / sequence.length();
		trace("frameDuration: " + frameDuration);

		for each(var frame:XML in sequence.*)
		{
			var sequenceFrame:ContentDisplay = LoaderMax.getContent(frame.@name);
			sequenceFrame.visible = false;
			addChild(sequenceFrame);

			var delay:int = (frame.childIndex() + 1) / sequence.length();
			trace("delay: " + delay);

			sequenceTimeline.insert(new TweenMax(sequenceFrame, 1, {onStart:show, onStartParams:[sequenceFrame], onComplete:hide, onCompleteParams:[sequenceFrame]}), delay); 

			function show(frameRef:ContentDisplay):void
			{
				trace("show");
				frameRef.visible = true;
			}
			function hide(frameRef:ContentDisplay):void
			{
				trace("hide");
				frameRef.visible = false;
			}
		}
		sequenceTimeline.gotoAndPlay(1);
	}
}
}

 

XML



         <_01>











Link to comment
Share on other sites

Hello Patrick,

 

Thank you for posting the code, it makes things much more clear.

 

What you are trying to accomplish is a cool and practical effect. From what I know the greensock family of tweening tools doesn't provide anything built in to achieve this goal as what you are doing isn't really a tween.

What you are doing is using a tweening platforms events / methods / features to drive a series of functions that produce your desired end result (which isn't necessarily a bad thing).

 

Your implementation does work and its a fairly clever approach. I just don't know enough about your project to assess why you are using TimelineLite for this functionality. Do you need to reverse this sequence or change its timescale at some point? I'm curious if your approach holds up it the tween is reversed.

 

What I'm getting at, is that unless its not 100% necessary that features of TimelineLite are being used, there are definitely simpler ways of getting a sequence of images to display.

 

If you really want the GreenSock platform to drive this sequence of images check out GreenSock's response and sample fla in this thread: viewtopic.php?f=1&t=4226

 

He mentions tweening a custom property of an object using a TweenLite/max. as that property's value changes it drives the positioning of a series of clips. I believe you could create your own "PNGSequence" object and tween something like its currentImageIndex property. currentImageIndex may be an index of your image in your xml object / loaderMax queue... whatever. as the currentImageIndex property changes... you can hide all images that don't have the same index value as currentImageIndex.

 

I think this type of approach will allow to add your animated sequence into a timelineLite as a single TweenLite and you will be able to benefit from all the features of the platform.

 

From looking at your code which illustrates your familiarity of loaderMax and everything else, I think you will really enjoy looking at the files in the link above and implementing something similar.

 

Carl

Link to comment
Share on other sites

@Carl: Thanks for the link! Trying to avoid Flash IDE for animations so I can port to other platforms. I was hoping to stick solely with GS, but did not realize that this functionality was not built in. :) This would be a valuable feature—but there would have to be some kind of measurable playback fidelity similar to the Flash IDE timeline (or a video file).

 

I considered an approach similar to viewtopic.php?f=1&t=4226, but it seemed like the playback performance would be adversely affected by rapid repositioning of graphics. The visibility property seems like it would take less CPU resource (maybe I am off the mark here).

 

----

Tried this method with reverse and didn't work. :/

Link to comment
Share on other sites

@Carl: Thanks for the link! Trying to avoid Flash IDE for animations so I can port to other platforms. I was hoping to stick solely with GS, but did not realize that this functionality was not built in. :) This would be a valuable feature—but there would have to be some kind of measurable playback fidelity similar to the Flash IDE timeline (or a video file).

Sure, this is totally possible but it's not a feature that really belongs in the platform itself because it would bloat things and make the API unnecessarily complex. Instead, Carl's suggestion is exactly what I'd recommend (read on...)

 

I considered an approach similar to viewtopic.php?f=1&t=4226, but it seemed like the playback performance would be adversely affected by rapid repositioning of graphics. The visibility property seems like it would take less CPU resource (maybe I am off the mark here).

Carl wasn't suggesting rapid repositioning of graphics - he was just using that example to illustrate the concept of building a separate class that has getters/setters that give you EXACTLY what you're looking for in a completely tweenable fashion. It's actually much cleaner than trying to do everything with onStart/onStartParams/onComplete/onCompleteParams and a separate tween for every individual frame.

 

I've whipped together an example for you (attached) that shows you how you can leverage the platform in a much more efficient manner. For example, your XML could be simplified a bit by wrapping your image data in a node and utilize its prependURLs attribute for convenience. The other benefit of this approach is that you can get the "content" of the LoaderMax instance and it'll give you an array of all your ImageLoaders' content. Here's the XML for 20 pngs:

 


<?xml version="1.0" encoding="utf-8"?>
<data>
<LoaderMax name="frames" load="true" prependURLs="assets/frames/">
<ImageLoader url="1.png" />
<ImageLoader url="2.png" />
<ImageLoader url="3.png" />
<ImageLoader url="4.png" />
<ImageLoader url="5.png" />
<ImageLoader url="6.png" />
<ImageLoader url="7.png" />
<ImageLoader url="8.png" />
<ImageLoader url="9.png" />
<ImageLoader url="10.png" />
<ImageLoader url="11.png" />
<ImageLoader url="12.png" />
<ImageLoader url="13.png" />
<ImageLoader url="14.png" />
<ImageLoader url="15.png" />
<ImageLoader url="16.png" />
<ImageLoader url="17.png" />
<ImageLoader url="18.png" />
<ImageLoader url="19.png" />
<ImageLoader url="20.png" />
</LoaderMax>
</data>

And then here's a FrameSequence class that allows you to simply pass an array of DisplayObjects to it and then it'll treat each element of that array as a "frame" and toggle the "visible" properties as necessary. You can tween the FrameSequence's "currentFrame" property to get the effect you're after. Go forwards, backwards, or whatever. Drop tweens into a TimelineLite/Max or use them standalone - it's completely flexible.

 

package {

import flash.display.DisplayObject;

import flash.display.Sprite;

import flash.geom.Rectangle;



public class FrameSequence extends Sprite {

protected var _frames:Array;

protected var _currentFrame:int;



public function FrameSequence(frames:Array=null) {

_currentFrame = 1;

this.frames = frames;

}



public function get currentFrame():Number {

return _currentFrame;

}



public function set currentFrame(value:Number):void {

value = int(value + 0.5); //much faster than Math.round(value)

if (value == _currentFrame || _frames.length == 0) {

return;

}

DisplayObject(_frames[_currentFrame - 1]).visible = false;

if (value > _frames.length) {

_currentFrame = _frames.length;

} else if (value <= 0) {

_currentFrame = 1;

} else {

_currentFrame = value;

}

DisplayObject(_frames[_currentFrame - 1]).visible = true;

}



public function get progress():Number {

return (_currentFrame - 1) / (_frames.length - 1);

}



public function set progress(value:Number):void {

this.currentFrame = value * _frames.length;

}



public function get frames():Array {

return _frames;

}



public function get totalFrames():int {

return _frames.length;

}



public function set frames(value:Array):void {

_frames = value || [];

if (_frames.length > 0) {

var obj:DisplayObject;

var i:int = _frames.length;

while (--i > -1) {

obj = _frames[i];

this.addChildAt(obj, 0);

obj.visible = Boolean(i == _currentFrame - 1);

}

}

}

}

}

Then to load the XML and see the results on the stage, tweening from frame 1 to 20 back and forth endlessly (just for kicks), here's the code:

 

import com.greensock.*;

import com.greensock.easing.*;

import com.greensock.loading.*;

import com.greensock.events.LoaderEvent;



//activate ImageLoader so that the  nodes in the XML are recognized and parsed

LoaderMax.activate([ImageLoader]);



//load the XML

var loader:XMLLoader = new XMLLoader("assets/frames.xml", {onComplete:completeHandler});

loader.load();



//container for the frames that are loaded (we'll populate this later)

var sequence:FrameSequence;



function completeHandler(event:LoaderEvent):void {

//instantiate and populate the FrameSequence with the content that was loaded. Remember, the "content" of a LoaderMax queue will be an array containing the content of all its child loaders.

sequence = new FrameSequence( LoaderMax.getContent("frames") );



//the FrameSequence is a Sprite. To make it visible, we need to add it to the display list.

addChild(sequence);



//tween the current frame forwards and backwards infinitely (just for kicks)

TweenMax.to(sequence, 5, {currentFrame:20, ease:Linear.easeNone, repeat:-1, yoyo:true});

}

Make sense? See how this is a cleaner solution than trying to build some sort of API into the tweening classes themselves? It keeps the core tweening engine lean and mean.

 

Download the fully-functional example (attached).

 

Anyway, I hope this helps.

 

FrameSequenceSample.zip

  • Like 1
Link to comment
Share on other sites

  • 2 years later...

Im trying to use the code and i cant get it to work.

I get this error
1180: Call to a possibly undefined method addFrameScript.

so then I change the extends from sprite to movieclip. then i get
1024: Overriding a function that is not marked for override.

for both currentFrame and totalFrame functions

 

I try to add in override but it still won't work.

 

any help would be appreciated.

 

Im using the latest version of greensock and cs5.5

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...