Hacking the Flash CS4 Motion Model to Create New Extensions

Justin | Animate/Flash,ExtendScript,jsfl,Misc,tips,Tutorials | Wednesday, March 4th, 2009

Here’s a quote from an email I sent to Chris Georgenes and David Stiller on 9/29/08 about an extension idea that I had using the new motion tweens in Flash CS4 (before I’d even used the application):

Given that the new motion tween creates a bezier path, I’m guessing that we’ll have access to creating such a path with JSFL. Which led me to think about creating that path in real-time, similar to the real-time drawing that I’d seen from ScribbleBot on Chris’s blog. Instead of scribbling a line in real-time, I’d be sketching a motion path. There would be a variable to determine “smoothness” so that it doesn’t create an unmananageable amount of new motion keyframes. And it could probably be done with a custom tool rather than a panel, so that the sketching could be done directly on the stage.

That also leads me to wonder if there’s a way to record the armature animation in real-time and convert it to a motion tween, similar to the feature that already exists in After Effects CS3.

I know, I’m a nerd. The first idea there became MotionSketch. I haven’t yet found a way to accomplish the second idea with the armature, but I have a few ideas.

Prior to the release of Flash CS4, I had gotten a little hooked on creating Flash extensions. It’s quite easy to create a classic motion tween with JSFL (Flash Javascript), you can simply make the following call: timeline.createMotionTween(). It was likely that createMotionTween() would remain for legacy support even though the name of the tween had changed from “motion” to “classic.” I’d seen all of the great new motion features demonstrated online, and I expected there might be an equivalent call for a new motion tween. When Lee Brimelow linked to the CS4 documentation, I went right to the Extending Flash section to see what had been added. I didn’t see any additions for the motion features, but I had also previously seen Lee’s post on Flash Camp in San Francisco. Fortunately, I live close to San Francisco and I decided to head over try out the application early, and maybe get a chance to talk with some of the Flash team about any undocumented features.

While at Flash Camp, I spoke with Richard Galvan and he directed me to John Mayhew, the engineer behind the new motion model in Flash. John was very affable and willing to follow up with me, but he didn’t know of any undocumented features offhand. Unfortunately, adding features to the JSFL API is usually somewhat of an afterthought because so much of the development time is spent on the new features themselves. I had a few ideas to use the new 3D features while at Flash Camp as well, but they were similarly left out of the JSFL API.

So I let those ideas go for awhile and focused on a different extension as my Flash Camp project. A few weeks later, I got a little antsy and I starting digging around in the Flash configuration directory for clues. I noticed two files in the Javascript directory named MotionXML.jsfl and MotionClipboard.xml. I started looking around in the JSFL file for undocumented commands that I could use, but to little avail. I think I even put some trace calls into the JSFL to spit out info when copying motion from the Flash IDE. I noticed that even though copying and pasting a new motion tween appeared to work the same way in the Flash interface as copying and pasting a classic tween, a new motion tween was not triggering the calls in the JSFL file. Looking at the XML file, I found that even though copying a motion tween wasn’t using the same JSFL calls, it was saving XML to the same file…just different XML. The classic tweens were generating XML with a root tag of <Motion> and the new tweens were generating a root tag of <AnimationCore>.

Flash seemed to be able to discern which type of motion it was copying or pasting and acting accordingly. So it occurred to me that I could grab the data from the motion clipboard and alter it before pasting it back. Additionally, if I wanted data from an existing tween, I could run a Copy Motion command, available to JSFL as of Flash CS3 thanks to Robert Penner’s Copy Motion feature, then go about altering and pasting. These are the extensions that I’ve created thus far using that very technique:

Below is a rundown of the steps I used in the extensions mentioned above. This technique can be used in lieu of the non-existent timeline.createMotionObjectTween() command. I refer to this as a “hack” because it’s an unsupported method, but given the complexity of what can be created with this new motion model, editing the XML is actually a fairly efficient way to go about creating/editing a tween. If the XML is not properly formed, it can cause Flash to crash when you try to paste the motion, or it can create some funky bugs in the Motion Editor. Be sure to test your code thoroughly before releasing anything for public consumption. The language is JSFL (used to automate and manipulate the Flash authoring environment). There’s a link to documentation for the AnimationCore XML listed in step 3.

(more…)

How to Control Things with Actionscript

Justin | ActionScript,Animate/Flash,tips,Tutorials | Monday, October 20th, 2008

When working with other designers in Flash, I generally serve as the last line of defense for unsolved functionality mysteries. I often find that there’s a mishap that has resulted from changed or lost instance names, effectively decapitating pieces of code. So how do you control things with Actionscript?

The short answer: Instance Names.

For the detailed answer check out this video tutorial using Actionscript 3.

The Actionscript has to know “who” you’re wanting to talk to. Just as we know human beings by name, and talk about them and to them by name, Actionscript references objects by name. A teacher might tell “Timmy” to sit down. Accordingly, your script might tell “circle” to move 10 pixels to the left. If no symbol with the name, “circle” exists, nothing happens; just as no one sits down if there’s no “Timmy” in the classroom.

Referencing nested MovieClips works the same way, just add a dot inbetween:
var clipReference = grandparentClip.parentClip.childClip;

Remember that a symbol name is different than an instance name. You can have multiple instances of a symbol on stage, but each instance name has to be unique. Instance names are set in the Property Inspector, symbol names are set in the Library.

Keep this idea in mind when working with Actionscript and it will make your life a whole lot easier.

New Flash Extension: FrameSync

Justin | Animate/Flash,animation,design,extensions,Tutorials | Tuesday, September 9th, 2008

This is a handy-dandy animation plug-in similar to Animonger’s AnimSlider, except that it uses frame labels and requires no other setup.

Update: The video tutorial is now live. See the extension in action!

I picked up this style of lip syncing in Flash from Chris Georgenes’ tutorial.

Update (8/26/09): A savvy user caught a stage refresh bug introduced in Flash CS4 with AS3. If you’re using Flash CS4 & AS3 and the symbol isn’t updating when you select a new frame from the panel, download the most recent version below (1.0.3 has the fix).

Update (8/16/10): Version 2.0 now has some great new features, including a “keyframe” mode, audio playback and frame navigation for Flash CS5, and performance improvements. See this post for more details on the updates.

Update (10/5/10): Check out SmartMouth, the new extension that automatically lip syncs.

Update (11/19/10): See Chris Georgenes demo FrameSync in his MAX 2010 Animation session.

Download

(compatible with Flash MX 2004 & up)
FrameSync.zip

Other Lip Sync Tools from Ajar Productions

Tutorial: A Simple Preloader, in detail

Justin | ActionScript,Animate/Flash,Tutorials | Tuesday, February 20th, 2007

Preloaders are one of the simplest bits of underutilized Flash programming
on the web. When making any kind of presentation on the web, whether it be
an interactive experience or a self-running animation, it is important to consider
user experience. It is important to be generous with the user, because we ask
that they be generous with us as they view our websites. Preloaders are also
important because they may retain busy or impatient users who would otherwise
think that nothing is going on when the page is merely loading without giving
feedback.

Not everybody’s a programmer, though. So I’ve provided this detailed tutorial
for anyone would like to add a preloader to their Flash web project.

Getting started:

I usually like to put the preloader in its own scene so that it doesn’t disturb
my main timeline. If you’re not familiar with using scenes in Flash, a scene
can be added in the following manner:
– Window > Other Panels > Scene
– click the “+” to add a new scene
– drag it to the top
– and double-click to rename it
– I usually name it “preloader” and from hereon out I will refer to
it as the preloader scene

Then make sure your actionscript is organized in its own layer in the preloader
scene:
– add a new layer and rename it to ‘actions’
– lock the layer so nothing accidentally get placed on the stage for this layer
– select the first keyframe on the actions layer and open the actions panel
– the actions panel can be opened by hitting the f9 key or by going to Window > Actions

Then enter the following code:

//loaderbar_mc is a movieClip containing a rectangle with its registration point at the left edge
//percent_txt is a dynamic text field
//note the 3 different display options (A, B, C)

stop();

loaderbar_mc._xscale =
0;

function preloading():Void{
var bLoaded:Number = getBytesLoaded();
var bTotal:Number = getBytesTotal();
var percentL:Number = (bLoaded / bTotal) * 100;

if (percentL < 100){
// (A) if you want to show text in the form of xx% loaded
percent_txt.text = Math.round(percentL) + “% loaded”;
// (B) if you want to show text in the form of xx Kb loaded/ xx Kb total
percent_txt.text = Math.round(bLoaded/1000) + ” Kb / “ + Math.round(bTotal/1000) + ” Kb” ;
// (C) if you want a loaderbar to grow with the % loaded
loaderbar_mc._xscale = percentL;
} else {
clearInterval(loaderInterval);
play();
}

}

loaderInterval = setInterval(preloading,25);

//make sure there’s a stop command on your main scene if it’s a one frame app

Now for a detailed description of what everything does:

(more…)

Page 5 of 512345