CMXtraneous: Flash

Right on the edge of useful

How to Tween a Mask Along a Motion Guide

Posted Saturday, September 30, 2006 9:34:53 PM by David Stiller

David Stiller

Masking in Flash is easy to implement.  Take an existing layer with artwork, create a new layer above it, draw your mask shape, then right-click/Command-click and choose Mask.  Done.  Include as many layers as you like in the masked stack by dragging additional layers slowly up toward the stack then slightly right until they snap into place.  Lock and unlock layers to show and hide the mask effect.

Your mask shape reveals the artwork beneath it and hides everything else.  This works with imported photos, shapes and symbols, text fields (remember to embed font outlines if text is dynamic or input), and even video.  In fact, you can add keyframes to the mask’s layer in order to tween it (shape tweening if the mask is a shape; motion tweening if the mask is a symbol).  But what if you want to tween your mask along a motion guide?  Select your mask layer and click the Add Motion Guide button at the bottom left of the Timeline panel:  nothing happens.  Interesting, right?  Where’s that motion guide layer?  Is it possible to tween masks in this way?  Well, let’s see.

An answer, short and sweet

Select the mask shape and convert it to a symbol if it isn’t one already.  A graphic symbol is fine (Modify > Convert to Symbol > Graphic).  Now select the mask again and convert it to a symbol a second time — again, a graphic.  At this point, you have a nested graphic symbol that is still part of a mask layer.  Double click this symbol to enter its timeline.  Inside this timeline, click the Add Motion Guide button and tween the mask along your motion guide path as if it were a normal symbol — which it is, in this timeline.  When finished, step back out to the main timeline and extend the mask’s span of frames long enough to let its inner tween play out.

How it works

This is a simple case of thinking outside the box.  Technically speaking, tweening a mask along a motion guide is not possible.  But given the nature of masks, which can be nested symbols, the same effect is achievable.  If you’re not comfortable with ActionScript, motion guides provide a powerful way to animate along complex twists and turns.  Combined with masking, the possibilities are that much more engaging.

Category tags: Flash

How to Validate an Email Address (ActionScript 1.0 or 2.0)

Posted Tuesday, September 26, 2006 11:38:20 PM by David Stiller

David Stiller

When it comes to programming, I generally like to work out my own solutions to a problem, just because it feels so good to finally nail a challenge.  Often enough, of course, someone else beats me to the punch.  Those are the times I study the code until I really understand it — which may require a number of readings! — and then smile in admiration of the author.  I’ve been a fan of Ralf Bokelberg’s programming for years and wasn’t surprised at all to find that he’s written an elegant approach to validating email addresses in ActionScript (pre-AS3; that is, without the benefit of regular expressions).

His approach uses the String class, which is straightforward enough.  One of its methods, String.indexOf(), allows you to check if a given string contains a certain character (or characters).  For example, you could check a doubted address by looking to see if it contains the @ symbol (clearly a requirement in email addresses):

function isValidEmail(address:String):Boolean {
  if (address.indexOf("@") < 0) return false;
    return true;
}
trace(isValidEmail("user@domain.com"));

If the string contains the passed-in character, the method returns that character’s position in the string.  In the above example, the @’s position is 4.  Because 4 is not less than zero, return false is skipped and the function returns true.  If the string does not contain the character in question, the method returns -1.

Of course, the above example is an extremely weak test — practically useless.  Sure, a missing @ makes an invalid address, but what if the given string has two such symbols?  What if the @ appears after the .com?  Those would be invalid addresses, and the above “catcher” would let those slip right through its fingers.

An answer, short and sweet

Ralf’s solution uses String.indexOf() and others, and he uses the methods in very interesting ways.  His solution is here …

http://www.bokelberg.de/actionscript/checkEmail.html

… and though it doesn’t use AS2’s syntax (num:Number, str:String, etc.), the script works just fine in ActionScript 2.0.

To use it in your own project, either copy/paste it into your timeline or save it as its own file and use the #include directive to pull it into your own code:

#include "bokelberg_validate-email.as"

Then pass in your string and check if the return value is 1.  Anything else means the address is invalid (poorly formed).  Before sending user input to a form mailer, for example, you might check the email text field’s content first …

if (checkMail(inputFieldEmail.text) == 1) {
    // LoadVars instructions, perhaps
  } else {
    // Email no good!  Alert the user, or clear the text field …
    inputFieldEmail.text = "";
 }

How it works

I usually include a “How it works” section in the “How to” posts, but in this case the explanation would take quite a few pages — and in a way, I’d feel a bit odd speaking authoritatively about someone else’s code (at least, about code that inspires and humbles me).

Note Ralph’s use of functions within a function and his compact, efficient use of String.indexOf() and String.charAt() as suppliers of true/false values to the if statements of the interior functions.  I love it.

As an interesting point, the very first couple lines (“implementation of the regular expression,” aka regex) shows a regex pattern that, in a practical sense, performs the same routine on a given string.  All those lines, nested functions and all, can be collapsed into a single, dense line of code that makes perfect sense to a regular expressions engine.  ActionScript 3.0 supports regex.  That pleases me to no end.  :)

Category tags: Flash

How to Position Movie Clips Based on Browser Resizing

Posted Friday, September 22, 2006 10:56:46 PM by David Stiller

David Stiller

It’s not hard to make a SWF resize itself to the dimensions of the browser.  All it takes, in fact, is to set the width and height attributes of the HTML’s <object> <param> element and/or <embed> element to 100%.  There are a number of ways to determine the SWF’s display, too:  show all (default) makes the entire movie visible while maintaining the original aspect ratio of the SWF (if the browser’s aspect ratio differs, you’ll get the equivalent of “letterbox” borders either horizontally or vertically); no border gets rid those potential borders, but may crop parts of the SWF instead; exact fit distorts the SWF, if necessary, to make the entire movie visible without borders or cropping.  See Adobe TechNote 12701 for complete details.

Fine and good.  Now, what if you want to allow the Stage to resize, but not its contents?  What if you want to adjust the position of various movie clips — such as a logo, navigation, or content area — in response to the Stage’s new dimensions as the browser is resized?  Luckily, that’s not hard either.  :)  Let’s take a look. 

An answer, short and sweet

Open a new FLA and draw a quick shape — a circle will do.  Convert the shape to a movie clip (Modify > Convert to Symbol…, then choose Movie Clip) and give the clip an instance name via the Property inspector.  For this example, let’s call it mcLogo.

Create a scripts layer and type the following into frame 1:

Stage.scaleMode = "noScale";
Stage.align = "TL";
var stageListener: Object = new Object();
stageListener.onResize = positionContent;
Stage.addListener(stageListener);

function positionContent():Void {
  mcLogo._x = Stage.width - mcLogo._width;
  mcLogo._y = Stage.height - mcLogo._height;
}
positionContent();

Test your SWF, and you’ll see the circle hug the lower right corner as you resize the SWF’s dimensions in Flash.  Either that, or publish to an HTML file and set the width and height attributes for both the <option> <param> element and the <embed> element to 100% and resize the browser.

How it works

In the first line, we’re telling the SWF not to scale itself.  In your HTML — this is important — you’re going to set the width and height to 100%, but the SWF itself will not scale to fit those dimensions.  In the second line, we’re telling the SWF to register itself to its upper left (top left) corner.

Next, an arbitrarily named variable, stageListener, is declared as a generic Object instance.  This object acts as an “ambassador” for the Stage.onResize event, so we need to assign a function to a new onResize property of our object, rather than of Stage directly.  In this example, the function is arbitrarily named positionContent() and is defined shortly below.  Note:  if you like, you may assign a function literal …

stageListener.onResize = function() {
  // instructions here
}

… but in this case, I chose a named function because you may want position dozens of movie clips, and it’s arguably “cleaner code” to define the function separately.  If you go the named function route, as we’re doing, make sure to omit the parentheses in this line, as shown.

The next line adds our ambassador as a listener to the Stage.  The Stage.addEventListner() method is what “wires up” the listener object to the object that dispatches the event (here, the Stage).

Finally, the custom positionContent() function tells mcLogo what to do.  In this case the movie clip’s _x property is set to the width of the Stage minus its own width.  That makes it hug the right side.  To center this clip, you could set its MovieClip._x property to half the Stage’s width minus half its own …

mcLogo._x = Stage.width / 2 - mcLogo._width / 2;

Follow suit for vertical positioning.  Makes sense, right?  Be sure to call the positionContent() function after you declare it, to make sure everything is positioned at the start, otherwise the Stage/browser would have to resize first.

By the way, this setup expects movie clips to be registered to their upper left corners.  If mcLogo’s shape was centered horizontally in its own timeline, you would only have to minus half its width from the Stage’s width to make it hug the right hand side.  If you want a 20 pixel buffer between this right-aligned clip and the Stage, account for that extra 20:

mcLogo._x = Stage.width - mcLogo._width - 20;

To keep a clip to the left side, set its _x to 0.

Keep in mind, you’re not limited to setting MovieClip._x and _y properties.  You may adjust a clip’s _width, _height, _xscale, _yscale … whatever you like.  Experiment and have fun with it!  For every clip you wish to position, simply add its entry to the positionContent() function.  Note, below, that an mcNav clip is being set to a position based on the original mcLogo clip.  Here, both clips would hug the right edge of the Stage, and mcNav would float below mcLogo, with a buffer of 20 pixels.

function positionContent():Void {
  mcLogo._x = Stage.width - mcLogo._width;
  mcLogo._y = 20;
  mcNav._x = Stage.width - mcNav._width;
  mcNav._y = mcLogo._y + mcLogo._height + 20;
}

Category tags: Flash

Flashforward 2006, Day 4

Posted Tuesday, September 19, 2006 9:35:20 PM by David Stiller

David Stiller

Note:  I started this entry on the actual fourth day of Flashforward.  Clearly, several days have passed since then — still catching up! — but I’ll leave my wording as is.

Sessions

Back to Phil Heinz for another Flex Builder 2 session.  Today’s was a follow-up on his intro to Flex from yesterday, this time delving deeper into socket connections for real time applications.  Honestly, the workflow efficiency of Flex Builder 2, as compared with Flash — for this sort of application; that is, “programs” rather than intros, games, and relatively “lighter” content — really is phenomenal.  I’m excited to see where RIA development will lead in the coming years, now that the Flex SDK (with compiler) is free and the Flex Builder 2 IDE is priced comparably to Flash.

I caught the tail end of Julian Dolce’s presentation on JSFL and was pleased to see that it had a decent turn-out.  This session, and talks with Scott McClurg — as well as planned Extension content for the companion CD to Chris Georgenes’ upcoming book — has inspired me out of a lull in my own JSFL work.  I had forgotten how much I love it!  (In a nutshell, JSFL allows you to programmatically accomplish practically anything doable in the IDE itself — like Photoshop Actions, but much more powerful.)

During the beginning of Julian’s session, I spent an hour or so with Branden Hall in the speaker lounge, checking out his Flow project under the hood.  Really, this is some very cool stuff.  I hope he and I can do some work together.

Next, David Castillo and Jennifer Benavides, who demonstrated a Flash app to help people improve their timing while learning salsa dancing.  This was the only session where audience members got on their feet!  ;)

I finished my day, and the conference in general, with a follow-up to Seb Lee-Delisle’s 3D work from yesterday; this one was on particle generators in AS2.  And finally, a cool look at Flash Player internals (the bytecode that ActionScript becomes) by Edwin van Rijkom.

Eats

Went to another fantastic restaurant — this time, I don’t even remember the name of it — and had an incredible, huge, rare Texas steak.  To put words to it would be to dishonor its memory.  Let’s just say it was a phenomenal meal.  :)  I loved it … and appreciated the company that night, which included Scott McClurg; Chris Georgenes; Silvia Pompei, who worked on Who Framed Roger Rabbit, The Simpsons, and other cool projects; Todd Sanders, and his lovely girlfriend.  Todd paid for the whole table, which was a completely unexpected treat.  It was a great way to conclude a terrific week.

Todd Sanders and me
Todd Sanders and me

Two Amys

While looking for an Amy I had helped on the Adobe forums, I ran into another Amy altogether.  It was funny, because when we first met, something told me this might just be the Amy from the forums.  After we had been talking for a while, I plumb asked her, “You wouldn’t happen to be Amy, would you?”  We were both surprised when she said she was.  We ran into each other at a bar later and had a great talk about Flash and also family.  Then I met the original Amy, too, which made me happy, because it’s always nice to put a face with the name.  I hope to keep in touch with both of them.

Surreal Twist Ending

I had to wake up early (3:30am) to get to the airport in time for my return flight.  Chris said I should wake him up to say goodbye, but I just didn’t have the heart.  Dude was snoring out some much needed sleep, which I envied, and I snuck out as quietly as I could.  ;)

My flight went from Austin to Newark, then Newark to Norfolk International — and I purposefully skipped the final leg to join Dawn and Meridian in New Jersey for a friend’s first birthday party.

While I finally crashed to catch up on my own lost sleep (you’ll see a pun in a moment), Dawn ran some errands with our friends and failed to yield on a left turn.  We’re still waiting for an official assessment, but the minivan may be totaled.  The right rear wheel was ripped off, the bumper missing … bad story.  But no one got hurt, not in our vehicle or the other, which is all that matters.  Kind of bizarre, because that worn tire on my plane coming in had to be replaced from Newark.

We talked Meridian through the experience a number of times.  She recounted the same events in German and English, so she clearly understands what happened, and knows that we’re all okay.  Mommy’s car is broken, and some men in New Jersey are going to try to fix it — or we’ll buy a new one.

So the whole trip has had its ups and downs.  Life never ceases to amaze.  I’m glad to be here.  :)  Now I’m working through business cards and hoping to keep up contact.

Category tags: Flash, On the Personal Side

Flashforward 2006, Day 3

Posted Thursday, September 14, 2006 9:27:55 AM by David Stiller

David Stiller

Today was another good one.  I’m glad I budgeted for this conference, because the sessions are good — and on paper, that’s the reason folks come — but in addition to that, Flashforward is a great opportunity to meet people of like mind.

Sessions

I started the day with Scott McClurg’s “My first ACCESSIBLE Flash Movie,” in which Scott went into a number of basics on how to use the Accessibility features in Flash.  I enjoyed his session, and we bumped into each other afterward more than once.  He’s a cool guy and very talented with Swift 3D, besides having a passion to make SWFs viewable by as many people as possible.

Next, I saw a number of ways to maximize the interaction between Flash and the browser, as presented by Robert Taylor and Tyler Wright.  I saw Seb Lee-Delisle break down his company’s simulated 3D soccer environmentPhil Heinz presented “Flex Builder 2 for Flash Programmers,” which was a great intro to Flex.  I found myself nodding in agreement several times, which was encouraging, because it means I’ve managed to grope forward somewhat in my own understanding of Flex Builder 2.

Finally, I saw and shook hands with Grant Skinner, who presented his views on potential pitfalls with the new garbage collection mechanism in Flash Player 9 (specifically, that of the ActionScript 3.0 virtual machine).  I have so much to sink my teeth into!  Really, Flash always keeps one step ahead of me, which is little like playing chess with someone who lets you catch up, then goes back to beating you 86% of the time:  that’s your best opponent, because the experience improves your game.  ;)

Eats

Todd introduced Chris and me to the Iron Works Barbeque for lunch.  The food was simply incredible … we each got the sample platter, which consists of a mountain-high pile of slow cooked meats.  I don’t remember when I’ve had such good food.

In the evening, I enjoyed the Flashforward Film Festival — lots of terrific entries, as usual — followed by an after party at Buffalo Billiards, again with plenty of free food and drinks.  I ran into Branden Hall at the bar and we got to talking about Lego Mindstorms and abstract strategy games such as mancala, Connect Four, Pente, Abalone, and the like.  It was fun, because I’ve admired Branden’s work for years, and he invited me to give him a call about his Flow project and maybe writing “patches” for his system.

Category tags: Flash, On the Personal Side

Flashforward 2006, Day 2

Posted Wednesday, September 13, 2006 10:47:33 AM by David Stiller

David Stiller

I made it!

Caught the last half of the keynote address.  Saw some cool quick glimpses of an in-house Flash 9 beta that happened so quickly, I barely remember what blipped in front of my eyes — but I’ll say this:  there were nifty thin vertical toolbars, somewhat like the Tools panel, whose icons seemed to slide open traditional panels like the Timeline, then slide them away again, maximizing Stage real estate (much cleaner than collapsible panels, which nonetheless take up space while collapsed).  I downed two cups of coffee while watching, so my observation faculties only kicked in after the projection screens went idle.  ;)

The coffee was a welcome relief.  I’d set my alarm for 5:00am in Houston, awoke, but fell right back asleep until 6:35.  Shuttles left every thirty minutes, and I had to be at the airport at 7:00.  Fortunately, that was my last small “lemon” event among my tales of woe.  The “lemonade” was that, amazingly, I woke up with zero bed head; literally, perfect hair.  So I was able to throw on my clothes (the same clothes) and walk right out the door to a cab.  Showers are for wimps, right?

Immediately after the keynote, I ran into Scott Fegette.  We had a great fifteen minute (or so) chat about all things Adobe, noting especially how well the Macromedia acquisition has gone.  I ran into Todd Sanders, too, who was originally going to let me crash at his house last night — that changed when Continental put me up at a Clarion in Houston, but the offer is very much appreciated.  Thanks again, bro!

Sessions

Session choices can be tough, because the presenters I want to see are often scheduled concurrently.  I attended a general Q/A roundtable with Mike Downey; saw an interesting prototyping app by Branden Hall, called Flow; saw Chafic Kazoun illuminate Component development for Flex; and rounded out the afternoon with a session on sound design by David Schroeder (great stuff!).  It was a nice mix, and of course my head is swimming with ideas, sparks, and possibilities.

The roundtable with Mike Downey reminded me what a “hidden” gem JSFL really is.  It’s not hidden, of course, but I’m surprised it isn’t more popular with developers.  A number of people had questions and feature requests for Flash that could be handled even today without too much effort in JSFL — mostly automation and asset management stuff.

In the evening, it was free food and drinks at a ten-year Flash anniversary party.  I hung out with Chris Georgenes, a good friend I only met face-to-face for the first time tonight, Scott, Todd, and a number of new faces.  I saw Chafic and thanked him for his Ultrashock tutorial on Flash MX 2004 Components.  Got into some brief discussion about Flex, which is great, because he may be able to answer some of my questions for an Adobe article in the works.  I’m glad to be here!

Colin Smith, Scott Fegette, David Stiller, Chris Georgenes
Colin Smith, Scott Fegette, David Stiller, Chris Georgenes

Category tags: Flash, On the Personal Side

Flashforward 2006, Day 1.5: Please, sir, I want some more

Posted Tuesday, September 12, 2006 2:06:15 AM by David Stiller

David Stiller

Shortly after I finished that last upbeat post, I boarded the plane to Houston; from there, it would be a short hop to Austin.  I shuffled my way to seat 15A and found a gentleman sitting in my seat.  He showed me his ticket — his also indicated 15A.  ;)  I moved a couple spots behind him, to an empty seat.  Soon thereafter, the fellow whose spot that was asked if I’d mind.  I moved again, settled in, still smiling.

Open Wide, More Lemons

The captain’s voice broke the gentle hubbub.  He informed us a technician had found that one of the plane’s tires was worn and might need to be replaced.  A few minutes later, that “might” turned into a “will.”  The odd thing to me was that the new tire, and the mechanic to install it, had to be flown in from Newark (that’s all the way from New Jersey to Virginia).  Bye-bye 5:38 flight!

Ahh, Lemonade!

We got into the air at 8:30pm.  I’m currently in a hotel, paid for by Continental (Clarion; not bad) and have a voucher for free breakfast.  If all goes well, I’ll catch the morning’s first flight to Austin and arrive fifteen minutes into Kevin Lynch’s Adobe Keynote address.  I can live with that.

This is beginning to remind me of The Muppet Movie, where Kermit and pals refuse to give up hope:  they will make it to Hollywood.

Four hours of sleep, baby!  I’m going to opt for the stack of pancakes.  And coffee.

Category tags: Flash, On the Personal Side

Flashforward 2006, Day 1: Makin' Lemonade

Posted Monday, September 11, 2006 4:20:13 PM by David Stiller

David Stiller

lol  Well, you may have heard the expression, “When life gives you lemons, make lemonade.”  That’s good advice, especially when things seem to go wrong all at once.

Quick Lemons Recap

My flight was scheduled for 11:52 this morning.  I needed to get to the airport (where I’m typing now) an hour before that.  As we were preparing to leave, the doctor’s office called to say they were packed today and could squeeze in Meridian’s cast appointment (see “Broken Bones”) twenty minutes from that moment.  That meant Dawn had to leave immediately and I’d have to find a ride (my truck died last week; I haven’t needed it because I’m working from home, so it’s just sitting in the driveway for now).  I had been talking up the airport experience for Meridian — “Papi fliegt heute auf einer Flugzeug” [“Papi is flying in an airplane today”] — but now she wouldn’t be able to see me off.

I called my sister Suzanne, who was happy to drive me.  Sweet.

Watching Dawn and Meridian leave, I noticed some flowers on the porch outside our house.  They had fallen from the hanging plant, which served as a nest for a pigeon and her two babies that Meridian and I had been watching for days.  Dawn had spotted a cat on our porch railing last night and shooed it away — but clearly, the feline had returned.  I hopped up on the railing.  No babies.  The mother pigeon was pacing back and forth in the grass, not twenty feet away.

Suzanne drove me to the airport.  I checked in to pick up my e-ticket.  Unfortunately, no e-ticket was listed for me.  The lady behind the counter was great — tried all sorts of alternative avenues to find my info — but nothing turned up.  I found an empty bench, fired up the wi-fi, and logged into Travelocity.  No e-ticket.  Dawn had researched an itinerary and found a terrific price, but hadn’t actually made the purchase.  :-p  (To her credit, Dawn has apologized profusely and repeatedly.  Ah, life.  Just gotta roll with it.)  The cheapest ticket today, on the spot, cost twice as much, but them’s the brakes.  I’m leaving much later and consequently arriving much later this evening.  On top of that, my return flight on Friday leaves at 6:30 in the morning!  (It had previously been a comfortable 10:40am.)

Lemonade, Please

In spite of this hassle, I’m still heading for Flashforward!  How cool is that!?

The fellow who’s meeting me at the airport, a friend of Chris’s and presenter, Todd Sanders, is at a dinner meeting until 10:00pm tonight, so my late arrival is actually more convenient for him.

I get the chance to go through my bags one last time and make quadrupley sure I didn’t forget anything.  ;)

Oh, and Meridian was able to see me off.  And I got to see her cast.  It‘s purple.

Category tags: Flash, On the Personal Side