Archive

You are currently browsing the archives for the Flash category.

Sep

24

Has the compiler been updated in Flash CS4?

By scott

The majority of the time I use MXMLC and COMPC to compile my work via ANT tasks. Most of my work is Actionscript only projects so I rarely use the Flash IDE compiler. 

Once in a while I find myself in the Flash IDE, mainly because I am working with an artists files, or I need to set up something on the timeline with document classes, or templated swfs that designers can base their work on. What I hate is the lack of compiler options in the IDE. Why can’t some of the command line compile options be available in the IDE?. Simple options like -load-externs, -link-report, externs, -external-library-path, -include-libraries, -includes, -library-path, -runtime-shared-libraries, and -source-path (to name a few).

With CS3 you can place a swc in the same directory as the FLA and use that for compile time checking and excluding classes in the compiled swf but this doesn’t work in most workflows. Why can’t I point at a shared swc outside of my project? A lot of our work runs in a global framework and for the most part designers don’t care about the framework or when it changes. If the designers could point at a swc on the server that can be updated at any time or in one common directory pulled out of source control they would recieve the updates and compile time checking without even knowing. You should be able to point to any swc or even a swc directory (again, like in Flex Builder).

Flash 8 had exclude.xml at least, even that would be a nice touch if that was offered again. I haven’t been able to find if any of this has been added to CS4, most of the discussion is around the visual tools. I’m ok with that, the designers deserve the love, the last release was all about the developer, AS3. Just curious if anyone knows if the compilation and workflow in the IDE is any better? I know about XFL, and I am excited to start playing with that. I already have a few ideas for workflow improvements.

 Also, Adobe if you’re reading this, can you please add an omit trace statements option in the command line compilers. I know it can be done with ANT and some RegEx trickery but it shouldn’t be that difficult. </endOfRant>

Sep

2

Chrome - Thank you Google!

By scott

Chrome has only been out a few hours and I have to say I already love it. My largest complaint is there isn’t a Mac version of it yet. 90% of my work is done on a Mac, of the 10% of the time I spend on the PC about 5% of that is spent in a browser. So what is so special about Chrome?

  • Extremly small download, 7mb (which includes 40+ languages)
  • Fast, fast, fast.
  • Virtualized JS engine (courtesy of V8 - no not the veggie drink), which I have heard is much cleaner thank Tamarin or Spidermonkey (haven’t had a chance to look myself yet).
  • Offloaded cache and processing using Gears.
  • Task Manager specific to the browser processes THANK YOU Google!
  • Geek mode THANK YOU again, however I do miss Firebug already.
  • Supplied developer tools work great, just need more.
  • Crashing doesn’t take down the whole browser, instead it only blows away the specific tab. This is due to multiple processes, one per tab to be exact.
  • And of course, searching Google is just that much easier.

The first thing I did was test the Disney suite of sites, better we catch the bugs before the evil QA department does (just kidding Eric, don’t assign me more bugs because of that last comment). The only major bug I have noticed so far is some redraw issues when AVM1 content is running inside of AVM2. Play some of the games on the Disney site and you will notice that the redraw hangs unless you scroll to the bottom of the page and back up. It seems to happen once AVM2 content is layered over top of AVM1 content. If no AVM2 content is layered over the AVM1 content everything seems to work fine. Sounds like more of a Flash Player bug then a Chrome bug.

The second issue I just noticed (which actually may be a feature) is multiple alpha tween animations seem to not animate, instead the content all pops on once all the tweened instances are complete.

I am not a huge fan of the default text rendering, probably one of the many reasons why the pages draw so quickly. IMHO the text looks like ass.

The other major problem is penetration, what is it going to take to get the world to download this browser. Sure the developer world is a buzz right now, but I don’t think the average joe is pumped about a new browser. Hopefully Microsoft and Mozilla learn or thing or two about browser development.

Jul

31

Presenting at Flash Forward 2008 in San Francisco

By scott

Long time no blog! I just found out I will be presenting at Flash Forward in San Francisco on August 21, 2008. At this point I know I will be presenting with Neil Ishibashi, Disney.com Art Director extraordinaire. As to what exactly we will be presenting, I’m not 100% sure. I know it will be along the lines of Engineer/Creative work flow on the all new disney.com. Our presentation will be at 10am - 11am on Thursday morning, directly following the Adobe keynote (not a bad lead in). Leave me a commnet if you are going to be there and if there are any particular items you would like us to cover in our presentation.

Jun

24

WALL-E takes over Disney.com

By scott

I haven’t blogged in a while, mainly because I have been extremely busy at work. One of the projects we launched tonight is the WALL-E takeover of the Disney.com homepage.

Earlier this year I was lucky enough to go up to the Pixar offices (yes it is an amazing office) to discuss this project. June 24 seemed so far away when we were storyboarding out the concept and presenting our ideas. I must admit, the final rendered version looks much better then those sketches and block animations we toyed around with.

From a technical standpoint there isn’t much to write home about here, however, it was a pretty cool project to say I worked on…sorta. Check it out, it will only be up for a few days.

wall-e takeover

Mar

6

Accessing displayObjects on the timeline after a gotoAndStop or gotoAndPlay

By scott

I have been meaning to add this to my blog for quite some time now. I have read a few postings related to this topic but I am surprised there aren’t a lot more people complaining about this. Personally I feel Adobe really dropped the ball with this bug. I guess I should explain what the bug is before I go on.

Lets pretend we’re creating a button, now I know most of my readers are developers and for the most part we would never create a simple button like this using multiple frames on the timeline. But we all know that designers love to use the timeline and create button states using frames and frame labels. I actually think this posting will help designers as much as it will help the developers who are working with said designers.

Now lets pretend our button has 3 states, up, over, and down and each state is represented on the timeline, 5 frames apart and the frame is labeled the same as each state. So the first frames label is “up”, the 5th frames label is “over”, and the 10th frames label is “down”. On each frame there is a MovieClip named button and each key frame has the same graphic just tinted differently to differentiate the states. Then on our code layer we set up MouseEvents for each state MOUSE_OVER, MOUSE_OUT, and MOUSE_DOWN, in each of the event handlers we move the playhead to each frame using the gotoAndStop method while passing in the frame label that we want the playhead to move to. Ok, so this is all straight forward. Very flash 4. The interesting part of this is when you try to access sibling displayObjects on the same frame right after we call gotoAndStop.

To illustrate this bug lets add a layer below the layer that has our button on it. On this layer add a keyframe at frame 5 and add a MovieClip, whatever you want, import a picture draw a shape, it doesn’t matter. Just as long as you give it an instance name of overClip. Right after we call gotoAndStop(’over’) try and trace (overClip). If you are not completely following me right now here is a picture of what my timeline looks like:

And our code will look something like this (excuse the timeline code, but it is the easiest way to demonstrate this bug).

button.addEventListener(MouseEvent.MOUSE_OVER, rollover);
button.addEventListener(MouseEvent.MOUSE_OUT, rollout);

function rollover(e:MouseEvent):void {
     gotoAndStop('over');
     trace('the instance name of the overclip is: ' + this.overClip.name);
}

function rollout(e:MouseEvent):void {
     gotoAndStop('up');
}

In the rollover function you will notice I added a trace that traces out the name property of the overClip that appears on the out frame (or frame 5 for those of you who like numbers). If you were to run this code you will notice that the rollover works, the playhead moves to frame 5 and visually you see the change, however, the trace statement throws the following error “TypeError: Error #1009: Cannot access a property or method of a null object reference.” Null?? How can that be, the playhead is at frame 5, and the overClip is on frame 5, why is overClip null? Good question! The other odd thing is if you trace out numChildren right after the gotoAndStop(’over’) call it will return the correct number of child displayObjects. How can the player know how many children there is but still throw an error saying we’re trying to access a null object reference?

This was a very common practice in AS2, especially in highly creative sites with both Flash Designers and Flash Developers. And as more creative shops start embracing Flash 9 I think this issue will become more common.

Well, the first thing I thought to do was to call stage.invalidate() before I called gotoAndStop(’over’), in theory this should force a redraw and fire the render event. Well it did fire the render event but I still couldn’t trace out the clip on frame 5. Arghhh!

The one thing I did notice is the error is only thrown the first time rollover is called. Everytime after that the reference to overClip traces out fine. So this got me thinking. It looks like displayObjects do not register until the current frame cycle is complete. For those who do not know, a frame cycle is two parts, first the code executes, once the code on that particular frame executes any display updates are executed (adding overClip to the timeline is a display update).

The first approach to get around this bug I thought up was to kick off a EnterFrame event in the rollever function, after the EnterFrame event is fired, it still didn’t trace out overClip. Then I thought maybe I need a second frame cycle to register everything because technically the EnterFrame event fires at the exact moment the playhead hits the frame which is exactly the same problem we already have. Ok, so lets allow for two EnterFrame events to fire, kill the event, and trace out overClip. Guess what, that works. Here is the code for this approach.

var count = 0;

button.addEventListener(MouseEvent.MOUSE_OVER, rollover);
button.addEventListener(MouseEvent.MOUSE_OUT, rollout);

function rollover(e:MouseEvent):void {
     count = 0;
     gotoAndStop('over');
     addEventListener(Event.ENTER_FRAME, rolloverDelay);
}

function rolloverDelay(e:Event):void {
     count++
     if (count == 2) {
          removeEventListener(Event.ENTER_FRAME, rolloverDelay);
          trace('the instance name of the overclip is: ' + this.overClip.name);
     }
}

function rollout(e:MouseEvent):void {
     gotoAndStop('up');
}

Yes this works, but imagine how complex this mess of code would get if we had a complex 12 state button with animations on each state. Not very practical.

The only way I could come up with to get around this issue was to create an EnterFrame that fires right off the bat, moves the playhead to the last frame of the timeline, and then returns it to the first frame. This ensures that everything that exists on the last frame will be registered and you will be able to access it immediately following the gotoAndStop(’over’) call. The key to this approach is only items that are still in the display list on the last frame will register. If you have a blank keyframe after overClip it will not register if the last frame of the timeline is beyond that. Here is the code for this approach.

button.buttonMode = true;
button.addEventListener(MouseEvent.MOUSE_OVER, rollover);
this.addEventListener(Event.ENTER_FRAME, frameentered);
this.addEventListener(Event.RENDER, rendered);

function frameentered(e:Event) {
     this.removeEventListener(Event.ENTER_FRAME, frameentered);
     if (overClip == null) {
          stage.invalidate();
          this.gotoAndStop(totalFrames);
     }
}

function rendered(e:Event):void {
     if (this.currentFrame == this.totalFrames) {
          this.gotoAndStop(1);
     }
}

function rollover(e:MouseEvent):void {
     trace('the instance name of the overclip is: ' + this.overClip.
}

Excellent, we’re making progress. But we are working with a very simple example, a two state button (up and over). What if we had a more complex button, say 4 states (up, over, down, and disabled), and at each state different assets were added to the timeline like so.

I know, I said complex, and this timeline is far from complex, where are all the tweens, and hundreds of layers, guides, and masks. Well, lets just pretend all that fun stuff is there for now.

If we were to try the last approach with this more complex timeline we still wouldn’t have access to the clips on the over and down frames. This is because we moved the playhead from the first frame to the last frame and back to the first frame again. The playhead never touched anything in between so the clips on the over and down frames would not have been registered yet.

The first approach I came up with to register the clips on all the frames was quite innovative, so I thought. Basically I used the currentLabels array property of MovieClip. For those who don’t know, the MovieClip class now contains a currentLabel and a currentLabels property. The currentLabel returns a FrameLabel object if one exists for the current frame that the playhead is currently on. A FrameLabel Object contains two properties, name, and frame. The name property is the frame label name and the frame property is the frame number (int) of the current frame the playhead is on. The currentLabels property of MovieClip returns an array of FrameLabel Objects containing all the FrameLabels for the targeted MovieClip. Using the currentLabels array I thought I could loop through each FrameLabel in the array and move the playhead to each frame label and once it is complete return the playhead back to the first frame. However, you cannot use a traditional for loop because the frame cycle will not occur until the for loop is complete. Instead I set up a counter variable and use an EnterFrame to move through each FrameLabel Object for targeted MovieClip. This approach is very similar to our previous approach with more stops in between. Lets call this approach the milk run. Here is what my code looked like for this approach.

button.buttonMode = true;
var count:int;
if (count == 0) {
     this.visible = false;
     addEventListener(Event.ENTER_FRAME, proxyframes);
     addEventListener(Event.RENDER, rendered);
}

function proxyframes(e:Event) {
     stage.invalidate();
     gotoAndStop(this.currentLabels[count].name);
     trace(this.currentFrame);
}

function rendered(e:Event):void {
     count++
     trace('render called' + this.currentFrame)

     if (count == this.currentLabels.length) {
          init();
          gotoAndStop(1);
          removeEventListener(Event.ENTER_FRAME, proxyframes);
          removeEventListener(Event.RENDER, rendered);
     }
}

function init() {
     this.visible = true;
     button.addEventListener(MouseEvent.MOUSE_OVER, rollover);
     button.addEventListener(MouseEvent.MOUSE_OUT, rollout);
     button.addEventListener(MouseEvent.MOUSE_DOWN, press);
     button.addEventListener(MouseEvent.MOUSE_UP, release);
}

function rollover(e:MouseEvent):void {
     gotoAndStop('over');
     trace(overClip.name);
}

function rollout(e:MouseEvent):void {
     gotoAndStop('up');
}

function press(e:MouseEvent):void {
     gotoAndStop('down');
     trace(downClip.name);
}

function release(e:MouseEvent):void {
     gotoAndStop('disabled');
     trace(disabledClip.name);

     //disable buttons if there was a parent clip parent.mouseChildren = false would also work.
     button.buttonMode = false;
     button.removeEventListener(MouseEvent.MOUSE_OVER, rollover);
     button.removeEventListener(MouseEvent.MOUSE_OUT, rollout);
     button.removeEventListener(MouseEvent.MOUSE_DOWN, press);
     button.removeEventListener(MouseEvent.MOUSE_UP, release);
}

So why doesn’t this work. Well if you remember what I said earlier, moving the playhead only registers the last frame that it was on. If you run this code you will notice the rollover and rollout methods return null but the release method traces out the correct value, this is because that was the last stop on our playhead milk run.

In order for this approach to work I would have to layout my timeline appropriately. Each state clip should be on its own layer with nothing after it (including blank keyframes) on the timeline, like so:

Now you will notice that the above code works, we are now able to trace out the extra clips that appear on each frame with a label. However, now that everything exists on the last frame we really don’t need to loop through each FrameLabel to register the clips, we can just use our first trick and move the playhead to the last frame, once it renders move back to the first frame. Even though the looping through the FrameLabels code is overkill for this example I thought I would keep it in so people know that capability exists.

So we are able to access sibling displayObjects now but there still is one functional issue. Since the frames are cascading on the timeline when the playhead is on the down frame both downClip and overClip are visible. Likewise, when the playhead is on the disabled FrameLabel upClip, downClip, and disabledClip are visible. That little bug is not going to slip by the creative department. Normally we would get around this issue by adding blank keyframes on the frame following where the extra clip was displayed. If we were to do this in our example the clips wouldn’t register because they do not exist on the last frame and we would be right back where we started. There are two ways around this, one involves more code (the developer approach), the other involves more keyframes (the designer approach). Both are valid.

The timeline approach basically consists of adding keyframes (not blank keyframes) on the frame after the frame where the extra clip appears and setting the alpha of the clip on the second frame to 0. This ensures that the clip is still on the display list in the last frame and allows it to register. With this approach your timeline would now look like so:

Depending on what else is happening in your application this approach may not work. This is when you have to resort to code (yay). Basically with code we do the same thing, however, instead of simply setting the alpha to 0 we’ll set the visibility to false. This only requires three extra lines of code which are included below.

stop();

button.buttonMode = true;
var count:int;
if (count == 0) {
     this.visible = false;
     addEventListener(Event.ENTER_FRAME, proxyframes);
     addEventListener(Event.RENDER, rendered);
}

function proxyframes(e:Event) {
     stage.invalidate();
     gotoAndStop(this.currentLabels[count].name);
     //gotoAndStop(this.totalFrames);
     trace(this.currentFrame);
}

function rendered(e:Event):void {
     count++
     trace('render called' + this.currentFrame)

     if (count == this.currentLabels.length) {
          init();
          gotoAndStop(1);
          removeEventListener(Event.ENTER_FRAME, proxyframes);
          removeEventListener(Event.RENDER, rendered);
     }
}

function init() {
     this.visible = true;
     button.addEventListener(MouseEvent.MOUSE_OVER, rollover);
     button.addEventListener(MouseEvent.MOUSE_OUT, rollout);
     button.addEventListener(MouseEvent.MOUSE_DOWN, press);
     button.addEventListener(MouseEvent.MOUSE_UP, release);
}

function rollover(e:MouseEvent):void {
     gotoAndStop('over');
     trace(overClip.name);
}

function rollout(e:MouseEvent):void {
     gotoAndStop('up');
}

function press(e:MouseEvent):void {
     overClip.visible = false;
     gotoAndStop('down');
     trace(downClip.name);
}

function release(e:MouseEvent):void {
     gotoAndStop('disabled');
     trace(disabledClip.name);
     overClip.visible = false;
     downClip.visible = false;
     button.buttonMode = false;
     button.removeEventListener(MouseEvent.MOUSE_OVER, rollover);
     button.removeEventListener(MouseEvent.MOUSE_OUT, rollout);
     button.removeEventListener(MouseEvent.MOUSE_DOWN, press);
     button.removeEventListener(MouseEvent.MOUSE_UP, release);
}

That’s it. Adobe, if you are reading this, please, please, please fix this bug. It is very annoying. It is obvious that Flash Player 9 was built with Flex in mind (aka no timeline) since that is all that was available when Flash Player 9 was released. I remember reading someone from Adobe admitting that on their personal blog, if I can find the link again I will post it in the comments below. I covered a lot here, but this bug goes even further. Sometimes Event.RENDER doesn’t even fire. In another related bug stop events on the first frame of nested MovieClip do not always work. Supposidly Adobe fixed this in version 9.0.45 of the player but as you can see by the comments on Emmy’s blog posting about the 9.0.45 release it was never really fixed. In fact we ran into this issue at work recently in the latest 9.0.115 version of the player.

I actually met with the Adobe Flash Player team last week and we discussed a lot of these issues, hopefully they will take these into consideration for the next release. To a developer they may seem like minor issues but designers and animators are going to have a difficult time getting around a lot of these bugs. If anyone else has any workarounds please feel free to explain them in the comments below.

P.S. this is my longest post ever, yay me.

Feb

11

Finally, Yahoo releases Maps API in Actionscript 3

By scott

Better late then never right? For about a year and a half, maybe even 2 years now, developers have been requesting an Actionscript 3 Yahoo Maps API. To cool the fires I wrote the Yahoo Maps Communication Kit, which was a hack that allowed you to use the Actionscript 2 Yahoo Maps component in an Actionscript 3 application. I am glad to say that the Maps communication kit is no longer needed. Head on over to the Yahoo Flash Developer center and download the real Yahoo AS3 Maps Component.

The component looks great, out of the gate I did notice one bug though. They didn’t account for the MOUSE_LEAVE event. You can see this bug in this example, start dragging the map and move the your cursor outside of the map, if you release your mouse while you are still outside of the map and move your cursor back into the map you will notice the map is still moving. A very minor bug. I can’t wait to use this component. I already have a few ideas where I can use it.

Thanks Yahoo! Let’s hope this doesn’t turn into the Microsoft Live Maps AS3 component ;)

Jan

30

Yahoo releases Astra v1.1.

By scott

My former peeps over at Yahoo just released 10 more components, 3 Flash and 5 Flex components. The also fixed some of the bugs that the community reported in the existing components.

For the Flash world Astra now contains an AlertManager, an AudioPlayback component, and a MenuBar component that works with the existing Menu component released in Astra 1.0.

For the Flex folk the kind gents on the Yahoo Flash Platform team have created an AutoCompleteManager, a few different ColorPickers, an IPV4AddressInput, a TimeInput component, and a TimeStepper component.

Nice work guys, and now that I am not part of the team and a user of Astra I say thank you for all your hard work.

Jan

23

Why is my progressive H.264 video not playing until the entire file is downloaded.

By scott

Now that H.264 video is supported in Flash Player 9.0.115 and FMS 3 is on the horizon we are getting ready to flip on the HD switch in our video player. We have been lucky enough to try out a few beta releases of FMS 3 and have had great success with streaming H.264 video without too many changes to our core video player component (both AS2 and AS3). However, I ran into an issue yesterday with progressively downloaded H.264 video. The video would play but it was not progressively downloading, it would download the entire file before it began playing. Not the user experience we were looking for. The files played fine in Quicktime, and they played fine in Flash when streamed from FMS 3, just not progressively.

Time to hit Google. I found a few postings, not many, probably not too many people using H.264 yet (so I thought). Turns out the problem lies within the encoding of the file and where the “moov atom” is stored. The moov atom is essentially the header information of the file. To progressively play a file this data is needed before the first frame of video can play. This data contains the appropriate meta data the NetStream class looks at when determining the length, size, etc of the video. The moov data in my .mov files were stored at the end of my videos and that is why the video wouldn’t play until the entire file was downloaded. The moov data needs to be at the beginning of the file in order to progressively stream video.

I figured others must have run into this issue and someone must have wrote a utility to move the header bytes from the end of the file to the beginning. Byte manipulation isn’t rocket science, close, but not quite. While searching I found an interesting tech note on the Adobe site and it turns out Adobe’s own video editing software is to blame for this. The quote below is pulled directly from the tech note explains the issue.

One important thing about playing an H.264 video file as progressive download is that the moov atom needs to be located at the beginning of the file, or else the entire file will have to be downloaded before it begins playing. The moov atom is a part of the file that holds index information for the whole file. Unfortunately, tools such as Adobe Premiere and After Effects place this information at the end of the file, but Adobe is working to fix this in a future update to the CS3 video production tools. This isn’t an issue for streaming the H.264 video files, however, so Flash Media Server users can breathe easy.

Why didn’t Adobe address this issue? Obviously they rushed this feature to market, Silverlight supported H.264 video and everyone was raving about it. I don’t know if Silverlight progressively streams H.264 video when the moov atom is at the end of the file or not. Can anyone confirm? Or maybe this was some sick marketers ploy to entice users to buy FMS 3, i doubt that but conspiracy theories are so much fun.

Scouring the web I did find a utility that moves the moov atom to the start of the file. Renaun Erickson ported a C app to AIR that moves the moov atom and resaves the file. Very impressive! Unfortunately it didn’t fix my issues, Renaun’s app only works with .mp4 files and the files I was working with are .mov files. Using Quicktime Pro I exported one of the .mov files to a .mp4 to see if Renaun’s app would then move the moov atom. Still no luck. As a last resort I tried a simple Save As from Quicktime to see if it would restructure the bytes so the moov atom was at the beginning of the file. Guess what, it worked! My progressive downloads now worked. I created a simple batch and saved out all my progressive videos using Quicktime.

It baffles me that Adobe would not have put more thought into this problem especially when their own software is the culprit. They talk about CS3 suite integration and this is the furthest thing from that. Adobe mentions that they will be releasing a CS3 update to address the issue, hopefully sooner than later, unfortunately this does not help people (like me/us) who already have hundreds of H.264 assets with the moov atom at the end of the file. Re-encoding the video would be a huge process, we are already using the video assets for other streaming services, now that Flash supports H.264 we were hoping for an easy switch to our Flash video player. Most of our video is streamed, and that works great, unfortunately the progressively downloaded video wasn’t an easy switch.

In the end, the video looks great! Watching 1.2mb and 3mb fullscreen video in Flash is unreal. Now if we could just get support for variable bitrates!!

Jan

4

Another Reflection and Prediction posting - Happy 2008

By scott

Well it’s a new year and I have held off posting anything. I didn’t really have a lot to say and I am not one to blog about nothing. A TV show about nothing was a huge success, but I can’t see a blog about nothing doing as well.

The past year has been a roller coaster for me and my family to say the least. We moved twice (4 times if you count corporate housing stops), one move was into a completely different country, I started 2 new jobs (Yahoo! and now Disney), my son went to 2 different schools, and somehow my wife found the time to get pregnant with our third child. So that means we won’t be resting anytime soon.

Looking back I wouldn’t of changed a thing as crazy as everything was. I learned so much professionally and personally. Professionally I have grown, my coding has improved greatly, for the most part I have been strictly working in AS3 and have absolutely no desire to turn back, unfortunately legacy code exists and AS2 will never go away, not for a long time anyway.

One of the best things of last year was working with Papervision, it has opened up a whole new world (or dimension) to me. I am a developer but I do have a creative side and being able to merge both halves of my brain using something like Papervision is truly amazing. Introducing the third dimension into interface design improves user experience because as humans we are trained to work with objects in 3D space and building everyday metaphors into the UI of our apps will make them that much better. Now if we could just get rid of the keyboard and mouse it would make obtaining those metaphors a lot easier. I think we are going to see a lot more 3D in the RIA space in 2008.

Last year we were all introduced to the iPhone, I am not going to drone on about it, but it truly is a great piece of hardware and software. Sure it is missing a few key things, but it is only a first release. Early this year Apple is releasing the iPhone SDK, you know engineers will be all over this SDK and it will only be a matter of time before some really cool apps and extensions are released for the iPhone. There is already a GPS extension in the works, GPS is the only thing I miss about my old LG phone.

So what else do I see happening in 2008. This is not a political blog so I won’t go into how I see the global economy switching from the U.S. dollar to the Euro, and I won’t go into the recession that everyone seems to be poo pooing which personally I think has already started. I also won’t go into how the Big 3 American car companies are digging their own graves and how the auto Unions are holding the biggest shovel. My all Chrysler employed family may disown me if I talk down the unions, oh wait, I think I just did.

2008 should be an interesting year from an RIA standpoint. There is a lot coming down the pipe. AIR is the first thing that comes to mind. Adobe has done a great job with AIR, I am just not sure how well it is going to take off out of the gate. In its current state it is a cool toy. I don’t think it is going to flop, I just think it will take a little time to fly, and maybe another major release. Personally I don’t agree with the whole AIR run time. I have used both mProjector and Zinc in the past to wrap swfs and create desktop applications. Both of these products allow you to create cross platform (Mac and PC, no Linux love) stand-alone apps with the Flash player included in the executable (if need be). These products had more hooks into the OS and file system, what they didn’t have was an embedded version of Webkit and a JS API. They also didn’t have the ability to interact with PDFs. So yes, AIR has it’s advantages, I just don’t agree with the runtime, it just adds a level of unnecessary complexity and doesn’t easily allow for easy deployment. IMHO. The apps should be stand alone so you can burn them on a CD and have them just work.

I mentioned the iPhone SDK already, this will be huge, of course people are going to try and monetize off of this, why wouldn’t they. What I am really hoping, as are most who are reading this blog, is the iPhone Flash Player we’ve been all dreaming about. There are rumors, lots of them, unfortunately only one guy (and probably a few hundred others) know for sure, Mr. Jobs, please enlighten us. The Internet on your phone is still a little watered down, you promised me the real internet in your ads, where is it? I know there would be memory issues, let’s face it, there are some very heavy flash sites out there. Already I have seen Safari on the iPhone close/crash when an image heavy page is loaded. By now I am sure most of you have heard about QVM or tamarin-tracing, could this be the beginning of something huge?

What else, Flex 3, all I have to say is wow. If you haven’t played with the beta do so now. The profiling and refactoring alone will blow you away. Flex has taken off big time, the one thing that puzzles me though is the number of recruiters who contact me with Flex work yet I still don’t see a ton of it out there in the tubes. Some of the jobs are with Fortune 500 companies. Either they are taking their sweet time to launch their “next big thing” or they gave up on using Flex because they couldn’t find the talent.

This year we will also see the Flex framework fully open sourced. Thank you Adobe, this is really going to change the landscape. Maybe we’ll finally see an AS3 decompiler.

EcmaScript 4, this is going to be an interesting one to watch. There has been a lot of rumblings from a few of the big players. Microsoft doesn’t like it. Once again, Microsoft and Adobe will be at each others throats.

IE8 will be released, yawwwwwwn.

Thermo, Astro, Buzzword oh my. H.264, Google Gears, WPF, it’s shaping up to be a good year. I have even heard some rumblings from the Cold Fusion camp, sounds like there is going to be some cool stuff coming from them.

I am not one to make resolutions, I believe if you have to wait till the beginning of the year to make a resolution you’re not very motivated. But this year I want to expand my horizons. I want to get into other technologies, I have played with a lot of things but I want to go beyond playing. Things like Ruby, Gears, Python. I want to get dirty with SQLlite. I also want to contribute more to the Open Source community. I also don’t want to move, don’t want to start a new job and maybe want to take a vacation for the first time in 4 years. We’ll see how much of this list I get to, with a third child on the way it could be tricky.

In closing, Happy New Year to all, I hope you and your families have a great 2008.

Dec

20

onDragOver, onDragOut, and onReleaseOutside in ActionScript 3.0 (AS3)

By scott

In AS2 there were three mouse events that I used quite often. onDragOver was thrown when the mouse button is selected and the cursor was moved over a MovieClip. This was useful to detect if another object was being dragged over a given clip. onDragOut was the opposite, this event was thrown when the mouse button was selected and the cursor was dragged outside of a given clip. And lastly, onReleaseOutside was thrown when a clip was pressed and the user dragged off the clip before releasing the mouse button. Releasing the mouse outside is a common way for a user to bail out of selecting a button among other reasons.

If you look through the AS3 documentation you will notice there are no MouseEvent.DRAG_OVER, MouseEvent.DRAG_OUT, or MouseEvent.RELEASE_OUTSIDE events. This does not mean that this functionality is not available, it’s just not as obvious. The following code shows how to recreate this functionality in AS3.

var button:Sprite = new Sprite();
button.graphics.beginFill(0x000000, 1);
button.graphics.drawRect(50,50,200,100);
addChild(button);

button.buttonMode = true;
button.addEventListener(MouseEvent.MOUSE_DOWN, buttonPress);
button.addEventListener(MouseEvent.MOUSE_UP, buttonRelease);
button.addEventListener(MouseEvent.MOUSE_OVER, buttonOver);
button.addEventListener(MouseEvent.MOUSE_OUT, buttonOut);

function buttonPress(e:MouseEvent):void {
     //the button is pressed, set a MOUSE_UP event on the button's parent stage
     //to caputre the onReleaseOutside event.
     button.parent.stage.addEventListener(MouseEvent.MOUSE_UP, buttonRelease);
}

function buttonRelease(e:MouseEvent):void {
     //remove the parent stage event listener
     button.parent.stage.removeEventListener(MouseEvent.MOUSE_UP, buttonRelease);

     //if the events currentTarget doesn't equal the button we
     //know the mouse was released outside.
     if (e.currentTarget != button) {
          trace('onReleasedOutside');
     } else {
          //the events currentTarget property equals the button instance therefore
          //the mouse was released over the button.
          trace('onRelease');
     }
}

function buttonOver(e:MouseEvent):void {
     if (e.buttonDown) {
          //if the mouse button is selected when the cursor is
          //over our button trigger the onDragOver functionality
          trace('onDragOver');
     } else {
          //if the mouse button isn't selected trigger the standard
          //onRollOver functionality
          trace('onRollOver');
     }
}

function buttonOut(e:MouseEvent):void {
     if (e.buttonDown) {
          //if the mouse button is selected when the cursor is
          //moves off of our button trigger the onDragOut functionality
          trace('onDragOut');
     } else {
          //if the mouse button isn't selected trigger the standard
          //onRollOut functionality
          trace('onRollOut');
     }
}

So let me explain what is going on here.

To recreate the onDragOver and onDragOut functionality we use the buttonDown property of the MouseEvent. The buttonDown property is a Boolean value that indicates if the users mouse button is selected when the event was triggered. If this property is true we know the user is dragging over or dragging out of the button. If the buttonDown property is false we can trigger our standard rollOver or rollOut functionality.

Recreating the onReleaseOutside functionality is a trickier multi-step process. First we must set up a MouseEvent.MOUSE_DOWN event listener on the button. Secondly we set up a MouseEvent.MOUSE_UP event listener on the same button. Third, in the MouseEvent.MOUSE_DOWN event handler we set up another MouseEvent.MOUSE_UP event listener on the button’s stage that triggers the same event handler as the MouseEvent.MOUSE_UP event handler (buttonRelease) that is set on the button. And lastly we check the currentTarget property of the event passed into the MouseEvent.MOUSE_DOWN event handler to see if it equals the button or the button’s parent stage. If the currentTarget equals the button we know the mouse button was released over the button and we can trigger the onRelease functionality. If the currentTarget property isn’t the button we can assume the user released the mouse button outside of the button. Each situation is different, button.parent.stage may not work in your application, you may have to traverse up the display list, possibly right down to the root child (the Stage) to succesfully detect the onReleaseOutside event. Below I have updated the buttonDown method to show a simple way of traversing up the display list as far as you can go and setting the MouseEvent.MOUSE_UP on the root child.

function buttonPress(e:MouseEvent):void {
     //the button is pressed, set a MOUSE_UP event on the root child in the display list
     //to caputre the onReleaseOutside event.
     var rootChild:DisplayObject = button;
     while (rootChild.parent != null) {
          rootChild = rootChild.parent;
     }
     rootChild.stage.addEventListener(MouseEvent.MOUSE_UP, buttonRelease);
}

Enjoy!