« October 2006 | Main | October 2006 »

October 06, 2006

The state of Web Development in 2006/2007

What web technologies will we all be using in 2007? Well...

There's an interesting report up at Sitepoint on the state of web development in 2006/2007. Perhaps the most important bit of useful information for designers is 'what will we be using in 2007?'.

Although the report doesn't actually tell us what we will be using in 2007 directly (i.e. via absolute figures), it does give us enough information to find out; there is a graph showing what we are using now, and another one showing what designers would like to be using in 2007. By transposing the two graphs together and normalising the results to 100%, we can draw up a graph that shows both what technologies/applications the industry is using now, and their future take-up.

I was sufficiently interested in seeing such a graph to create it myself, and here it is. The lower, solid bars show the percentage of designers using each technology/application now, and the ghosted bars above them show the predicted change in the near future. The final size of each bar (solid plus ghosted) gives the absolute number (in percent) of all designers who will be using each technology in 2007.

Current web technology use for 2006 and predicted use in 2007
Source : The State of Web Development 2006/2007, SitePoint Pty Ltd. and Ektron, Inc, August 2006.
Copyright (c) 2006, SitePointPty Ltd and Ektron, Inc.

As you can see, Flash and JavaScript Libraries have pretty much the same take-up today; 35% of all designers use each. AJAX lags both at less than 30%. Usage of both Flash and JavaScript is set to rise, but AJAX will soon be the dominant one.

My feeling is that AJAX and Flash will tend to be used together in the future rather than competing, and the increase in take up of AJAX is more a sign of browser stability and cross browser compatibility in HTML/CSS/JavaScript than anything else - and that's a good thing for everyone. To see a good example of AJAX/Flash integration, take a look a lastFM, and if you really want to have a laugh, you can always take a peek at my musical tastes. The site pages are mostly AJAX, but the LastFM desktop player is a Flash web application

Also, I have a feeling that the list of technologies/applications listed in the graph above is a little (mis)leading. If web technologies related to the upcoming Microsoft Vista release and perhaps Adobe Flex (which is sufficiently diverse from Flash to warrant its own heading, and a closer competitor to AJAX than Flash) were listed, the results would be significantly different.

My guess is that many more designers will be wanting to look at XAML and Microsoft's new vector/3D UI technologies, especially if the web portions of the new stuff ends up being cross-platform. Also, many exisitng Flash users would potentially want to learn Flex/MXML for 2007 as Flex is more web application oriented.

Still, its all food for thought, and yet another good indication that the web is becoming a more interesting platform, especially for motion graphics and web application designers/developers.

As a final aside, there's also a more general set of predictions at Imagining the Internet. Almost as interesting are the predictions made in the early 1990's at the same site, as seen here.

Posted by motiongraphics at 04:38 PM | Comments (2)

October 03, 2006

AS2.0 development gotchas

In the last few months I've been working on a number of largish AS2.0 coding tasks. I've come across a few problems/bugs that I've spent literally days debugging/rewriting.
Just so you don't have to go through the same pain, here's a quick lowdown on my top timewasting/obscure-but-common problems and issues, with a fix for each.

You need better realtime debugging tools when writing classes

The debugger panel just doesnt hack it when using the standard Flash IDE, and trace isn't that good either because its limited in what it can do (it simply traces values to the output panel).

Fix: You can trace function calls. This one is so easy once you see it, but many coders have never seen it. If you are writing a class, create a debugging method called snapShot() that itself traces a snapshot of the relevant values/states in the class (and returns null to the calling trace()). Thus, whenever you want to debug an error, use

trace(snapShot());

Rather than using trace() to output text, we use it to call a debug function. This way the snapShot() function can do all sorts of things other than just display data (it can contain test harness logic that forces values for example). As with all trace actions, this trace is not exported to the final swf, so the debug code never gets invoked in the final swf. Sweet!

Don’t assume that delete actually deletes immediately.

When you use the delete action, you are relying on the Flash player’s memory 'garbage collection', and this is dangerous for two reasons. Firstly, the garbage collection routines are player specific; Flash player 8 is better at garbage collection than Flash player 7, but how good either are is not a documented feature. Also, even though you may delete something, the something may be forcing itself to be kept in memory in a number of ways (such as references that are still active, particularly if they reside in anonymous functions).

The issue of delete not deleting immediately is not normally an issue, except when you are creating event driven code where the events occur very quickly, (i.e. on the same frame). The fact that something you thought you deleted is actually still there may then cause all sorts of problems, especially if you can’t always be sure of the order of events (e.g when your code is at least partly driven by events generated by external webservice returns or the user, and both generate lots of graphic changes in the UI).

Fix: If you want something to be deleted immediately, make it null first. That way, you are much less worried if the something is not actually deleted right away because you know its value is deleted right away. For example, if you want an onEnterFrame to become inactive right away, don't use:

  delete this.onEnterFrame;

Consider doing this instead:

  this.onEnterFrame = null;
  delete this.onEnterFrame;

Another closely related issue I’ve seen a lot is where you are implicitly expecting Flash to delete local variables in event handlers, particularly those associated with recieving data. For example, Flash may not be deleting XML instances when event handlers end. The fix here is to:

  • Explicitly clear local XML instances by setting them to null.
  • Avoid using anonymous functions. The Flash garbage collection seems to be particularly bad with them (its better in Flash 8 and later, but how much better is not a documented feature, so don’t count on it). The Flash 7 player (and previous versions) are notorious for memory leakage, especially when you are building web applications. In the testing I've done, this seems to be largely due to XML instances not clearing themselves from memory.

Following the fixes seen above makes the Flash player much more stable when there's a lot of communications with a back-end via XML/webservices going on, especially for Flash 7 and previous versions of the player (and although we have Flash player 8 and 9 at the time of this writing, most projects still specify compatibility with Flash player 7 as a requirement).

Avoid using this in an AS2.0 class because scope bugs are hell to fix.

Okay, I know some people disagree totally with this, but I’ve found time and time again that using this in a class is a major timewaster when it comes to debugging. The problem here is that unlike other languages, in ActionScript, this can very easily change in a class containing event handlers. It can be difficult to see that this has changed if you have a scoping bug because this will always have a valid value, whereas lots of other things will become invalid (such as all the class properties because you are no longer scoping the class). The biggest problem in fixing this bug is that the situation causing the bug (an incorrectly scoped event handler) isn't persistent - once the event handler finishes, the properties magically become defined.

You can (and always should!) prevent this from changing throughout a class by using Delegate.create() when defining event handlers, but the problem is when you have bugs; if you forget or fail to force scope to remain unchanged, this is still equal to something (it usually becomes scoped to a property that can have event handlers, such as a movie clip or XML instance, rather than to the class). It would be far better if this became invalid, because that’s easier to debug.

Fix: Instead of using this directly, use a property that is equal to this:

  // In property definition…
  private var me:MovieClip;
  ...
  ...
  // In constructor…
  me = this;

The cool thing here is that property me will be undefined if you ever go out of class scope, thus making scoping errors quicker to pick out when debugging (because code that doesn't work is easier to fix than code that works but does the wrong thing). I can’t emphasize how much time you will save by doing this; most timewaster bugs in class based code are to do with scoping error.

A more structured solution is to ensure that any property that has event handlers is coded up via its own class. That way, this in the event hander and this in the class are actually the same thing. My feeling here is that you are then (at least partly) working around the problem rather than going head-on at the issue and fixing it; you should only be creating new classes if your model requires it, and not to work-around Flash.

It should of course be noted that the problem is less important in AS3.0... but AS3.0 is still beta and it will be at least the middle of next year before it bcomes mainstream.

Class inheritance doesn’t know about streaming.

Class inheritance works well when you are creating components because registering classes to movie clips causes the classes to load at the same time as the movie clips. You can also define which frame classes that are registered to movie clips load (File > Publish Settings > Flash Tab > ActionScript Version: Settings).

Class inheritence doesn’t always work when you have classes that are simply datatypes (i.e. they are not registered to a movie clip). In this situation, a subclass may load before its superclass, which is very bad for your code; super() stops working because the superclass is not yet available. Worse still, Flash won’t tell you the error occurs. Even worse still, you probably won’t even see the error until you put the application online!

Fix: The simple (and obvious) solution is to fully preload your application before running any class based code. The problem is that this is not always possible, particularly for more complex applications. A better way is to explicitly force classes to load at a certain frame ('better' because it sounds like a fix rather than a structural workaround!). You can do this by calling a static class method on the required frame. By using a static method, you can force the class to load before you start creating instances.

Instances don't contain methods and properties; they contain data.

Okay. This is not really a bug but a way of thinking when writing AS2.0 code. All reference material you read on OOP tells you about classes >> methods >> properties. Thus, when you start writing classes, your mindset in centered around methods and properties, and you may fall into the trap of seeing classes as defining 'containers of logically related code'.

Classes define containers of data. This data is held internal to each instance (or static class), and methods and properties are merely the external interfaces to that data. This is an important mindset to work to when defining your classes, but its always easy to forget...

Thus when defining a class, think first in terms of what data each instance should contain, and then think about the inerfaces external code will need to access that data. What you should not do is simply think about what methods and properties the instance should have, then backfit the data to support it. You can tell if you have done the latter, because a couple of months down the line, your classes will start to seem unwieldy and more trouble maintaining than they are worth!

Posted by motiongraphics at 12:34 AM | Comments (6)

October 02, 2006

Designing motion graphics pt3: Code

The first part in this piece introduced the high level design concepts in motion graphics. The second part introduced a metaphor for code driven motion. In this part, we will look at how to convert the metaphor into code.

All the files used in this entry are available as a zip file here (Flash MX 2004, approx 30k). I have written the code in untyped ActionScript so that Flash MX users can follow it. Flash MX 2004/Flash 8 users should not feel too left out as I will be discussing an AS2.0 class based implementation in the next post.

It is easy to use ActionScript to create movement. You simply attach an onEnterFrame event handler to a movie clip, ensuring that the handler varies one or more property of the movie clip over time. The simplest example of such an onEnterFrame applied to a movie clip, myMC, would be

1  myMC.onEnterFrame = function(){
2    this._x += 5;
3  }

Assuming you have a movie clip called myMC on the first frame of the main timeline, and the above script is attached to frame 1 of the main timeline, you will see myMC move left-right across the stage. Why? Because the onEnterFrame increases the _x property of myMC by 5 per frame, causing myMC to move 5 units to the right every frame. By changing the script to vary a different property, we can change the nature of the animation. For example, changing line 2 to the following will fade out the clip rather than move it:

2   this._alpha -= 2;

The code above explains the concept of scripted motion (i.e changing a movie clip’s property per frame creates animation) but it is not really an example of useful animation for the following reasons:

  • There is no way to define when the animation starts or stops
  • There is no way to make the movie clip, myMC end up at a particular place.
  • The animation is linear, leaving the clip with no sense of mass. A better animation would include acceleration (or 'easing' if you are an animator).

In the previous entry in this piece, I ended by introducing the following 4 points as the basis for useful motion graphics code;

  1. We need an animation trigger. The trigger is the animation start event.
  2. We need an animation target. The target defines the animation's goal. The target is similar to the end keyframe in a tween; it defines the end point of the animation. It should be noted that a scripted target is very different from a tween keyframe though. A scripted target can change during the course of an animation. Further, by changing the target every time the same animation is run, we can make the animation look different every time.
  3. We need to define code that animates the clip moving towards the target. This code defines the animated transition.
  4. We need a halt condition. The halt condition simply detects when we are at the target and stops the animation when this occurs.

I call this system target driven motion. The simplest example of target driven motion would be one that moves a movie clip to a position (x, y) on the stage. Let’s see how we would write this code via a worked example. We will make a movie clip move towards a user-selected point.

Create a new Flash document and set the frame rate to 24 fps (Modify > Document or double click the frame rate below the timeline to access the frame rate).

On the stage, draw a small circle and convert it to a movie clip called ball. Give the instance on the stage an instance name of clip.

Add a new layer called actions, placing this above the current layer. For the busy/lazy, the file targetDrivenMotion01.fla includes all steps to this point

Flash workspace

The first thing we need to define is the trigger. In the simplest case, the trigger is an event*. We will make the animation start whenever we click on the stage. Select frame 1 of layer actions, press F9 to bring up the actions panel and enter the following code

clip.onMouseDown = setTarget;

Whenever you click, function setTarget() will run.

* In more complex code, the trigger can also be a condition. For example, in a video game, you might want the enemy alien to fire its laser gun at the player’s ship when the condition ‘alien is pointing at the player’ occurs. Thus, this condition is the trigger for the laser. Incidentally, the halt condition for the laser would be ‘I am off the screen or I have hit the player’.

Next, we need to write function setTarget(). Add this function above the current line as shown

 1 function setTarget() {
 2   this.targetX = _xmouse;
 3   this.targetY = _ymouse;
 4 }
 5 //
 6 clip.onMouseDown = setTarget;

The file targetDrivenMotion02.fla contains all steps to this point.

Function setTarget() sets our target. When we test this fla we will not yet see anything change onscreen but if we debug, we can see the target being set in the code. Do this by pressing Control+Shift+Enter (or select Control > Debug Movie), then click the continue icon (green ‘play’ icon at the top right) on the debugger window. In the top left pane of the debugger, select _level0.clip and in the middle left pane select the variables tab. Every time you click on the stage, you will see the values of targetX and targetY change.

Debugger panel

NB - if you have never used the debugger before, the middle left pane may be hidden behind the call stack. Drag the call stack pane down to reveal the middle pane.

Okay so now we have a trigger for our animation, and have captured our user-defined target position. The next step is to animate our movie clip to the target.

Add the following code (lines 4 and 7-13 are new, and targetDrivenMotion03.fla contains all steps to this point):

 1 function setTarget() {
 2   this.targetX = _xmouse;
 3   this.targetY = _ymouse;
 4   this.onEnterFrame = transition;
 5 }
 6 //
 7 function transition() {
 8   var deltaX = this._x-this.targetX;
 9   var deltaY = this._y-this.targetY;
10   trace("delta = ("+deltaX+","+deltaY+")");
11   this._x -= deltaX/3;
12   this._y -= deltaY/3;
13 }
14 //
15 clip.onMouseDown = setTarget;

Function setTarget() now calls function transition() as an onEnterFrame. The new function transition() animates the movie clip towards the target position.

How does transition() do this? Well, it uses the common Flash ‘inertia effect’; every frame, the code looks at how far the target is (deltaX, deltaY) and moves 1/3 of this distance towards the target.

Lines 8 and 9 define deltaX and deltaY. Lines 11 and 12 move the clip 1/3 of the distance towards the target position (targetX, targetY).

Relationship between deltaX, deltaY and targetX, targetY

If you test the movie, you will see that the clip moves to the last position you click, and then stops. Well, that’s what it seems to do, but the trace at line 10 tells us a different story. The output panel will continiously fill with trace values because the clip is constantly moving, even though the animation seems to stop after a second or so. The clip seems to stop because the distance it travels per frame gets smaller every frame; so small that we no longer see a movement, but the code is still creating animation.

Our animation never stops because we have not put in a halt condition. It’s important to realize that although the animation appears to stop, this doesn’t mean that the code stops executing. If every animation in a site never stopped once started, the Flash player would slow down, resulting in sluggish performance. Many designers complain about the slow speed of the Flash player, when in fact the real problem may be caused by motion graphics code that never stops when it is no longer needed!

The halt condition is almost always an if() condition that checks whether we have reached the target position.

Add the following code (lines 13-17) to the function transition() to add out halt condition (or look at targetDrivenMotion04.fla:

 7 function transition() {
 8   var deltaX = this._x-this.targetX;
 9   var deltaY = this._y-this.targetY;
10   trace("delta = ("+deltaX+","+deltaY+")");
11   this._x -= deltaX/3;
12   this._y -= deltaY/3;
13   if ((Math.abs(deltaX)<1) && (Math.abs(deltaY)<1)) {
14     this._x = targetX;
15     this._y = targetY;
16     delete this.onEnterFrame;
17   }
18 }

The if() checks for the clip being within one pixel of the target position (in both x and y). When this occurs, the code moves the clip to the target position (lines 14, 15) and stops the animation (line 16). When line 16 executes, we delete the onEnterFrame, and no code is running.

The trace at line 10 is starting to get a little intrusive, so delete it.

Our full listing now contains the basic code for usable and efficient motion graphics. Here it is in its entirety:

 1 function setTarget() {
 2   this.targetX = _xmouse;
 3   this.targetY = _ymouse;
 4   this.onEnterFrame = transition;
 5 }
 6 //
 7 function transition() {
 8   var deltaX = this._x-this.targetX;
 9   var deltaY = this._y-this.targetY;
10   this._x -= deltaX/3;
11   this._y -= deltaY/3;
12   if ((Math.abs(deltaX)<1) && (Math.abs(deltaY)<1)) {
13     this._x = targetX;
14     this._y = targetY;
15     delete this.onEnterFrame;
16   }
17 }
18 //
19 clip.onMouseDown = setTarget;

The following version of the code has liberally added trace() actions to show what is actually happening (lines 2, 5, 10, 16). See also targetDrivenMotion05.fla.

 1 function setTarget() {
 2   trace("\n\nSetting target...");
 3   this.targetX = _xmouse;
 4   this.targetY = _ymouse;
 5   trace("Starting animation towards target...");
 6   this.onEnterFrame = transition;
 7 }
 8 //
 9 function transition() {
10   trace("Animating.");
11   var deltaX = this._x-this.targetX;
12   var deltaY = this._y-this.targetY;
13   this._x -= deltaX/3;
14   this._y -= deltaY/3;
15   if ((Math.abs(deltaX)<1) && (Math.abs(deltaY)<1)) {
16     trace("Reached target.")
17     this._x = targetX;
18     this._y = targetY;
19     trace("Stopping animation.");
20     delete this.onEnterFrame;
21   }
22 }
23 //
24 clip.onMouseDown = setTarget;

If you test this version of the code, you will see the different stages of the animation listed in realtime via the output panel:

Flash output panel

The first trace, Setting target... shows the code setting the target position, and this occurs as soon as you click. The code then sets the onEnterFrame that will control the motion to the target (Starting animation towards target...). The animation runs over a number of frames (the exact number is shown by the number of times you see Animating.). Finally, the halt condition detects that the target has been reached (Reached target.) and the animation is halted (Stopping animation).


The animation has a definite start and stop point, and the code only runs for as long as the animation occurs. More importantly, we can easily change this code to create different transitions:



  • If we want a different type of motion instead of the intertia effect, we change function transition()

  • If we want to change the trigger event, we simply change line 19

  • If we want to change the conditional at line 12


So are there any good examples of this sort of code? Well, a better way of looking at the question would be to try to find ActionScript based Flash sites that don't use something like this code! Try deconstructing a few cutting edge sites and see all the places where target driven code is used.


Whilst writing this entry, it occurred to me that the code is a good candidate to be converted to classes, and I'll be looking at how to do this in the next post.


The content in this article is futher expanded in chapter 7 of the Book Flash 8 Savvy (Sybex), chapter 7, and a forthcoming Flash 9 book I am writing with Adam Phillips (O'Reilly).

Posted by motiongraphics at 02:28 PM | Comments (1)