Converting Flash Animations to


In preparation for a talk I was going to give at the last Shanghai Barcamp, I converted a Flash animation class by Grant Skinner to the HTML5 <canvas /> tag. Sadly, I didn't have time to finish the demo before the event so I've decided to post it here with a breakdown on the conversion process from Flash -> web standards.

To start off, take a peek at the Flash reference. The animation has a "target" DisplayObject (shown in red) that animates across the stage with x number of chasing DisplayObjects.

The AS3 Wander class acts as a decorator on a DisplayObject so it doesn't directly contain any drawing logic, only mathematical calculations. This allows the conversion from a Class based language to a prototype based language to be pretty straight forward. Here's a simple example of the conversion process.

The starting AS3 Class:

  1. public class ExampleClass{
  2. private var _count:int;
  3. private var _autoUpdate:Boolean;
  5. function ExampleClass(count:int){
  6. _count = count;
  7. }
  9. public function set autoUpdate(value:Boolean):void{
  10. _autoUpdate = value;
  11. if(_autoUpdate){
  12. addListeners();
  13. }else{
  14. removeListeners();
  15. }
  16. }
  17. public function get autoUpdate():Boolean{
  18. return _autoUpdate;
  19. }
  21. public function start():void{
  22. //do something important
  23. }
  25. private function addListeners():void{
  26. //add event listeners here
  27. }
  29. private function removeListeners():void{
  30. //remove event listeners
  31. }
  33. }

A simple conversion:

  1. var ExampleClass = function(count){
  2. //initial function pass is essentially the constructor
  3. //note the argument is the same as in the AS3 Class
  5. //initialize private variables
  6. //remove all the AS3 types
  7. var _count = count,
  8. _autoUpdate = true;
  10. //private functions
  11. var addListeners = function(){
  12. //add event listeners here
  13. };
  14. var removeListeners = function(){
  15. //remove event listeners
  16. };
  18. this.setAutoUpdate = function(value){
  19. _autoUpdate = value;
  20. if(_autoUpdate){
  21. addListeners();
  22. }else{
  23. removeListeners();
  24. }
  25. };
  26. this.getAutoUpdate = function(){
  27. return _autoUpdate;
  28. }
  29. this.start = function(){
  30. //do something important
  31. //has access to all private/public variables/functions
  32. }
  33. };

For the full conversion, see the library source file below.

After converting the class into javascript, I then had to come to grips with a couple of the core differences between Flash and the <canvas> element. Here's a quick list of the hurdles I had to get around:

  1. Flash executes code on a frame-based system. Grant Skinner's Wander class used the "enterFrame" event dispatched at the lowest level in the Flash player to update the x, y, and rotation of the particular DisplayObject. To mimic the "enterFrame" event, I created a FrameCounter object that could queue functions to execute on a set interval (via setInterval).
  2. The Wander Class is tightly coupled to the DisplayObject interface in Flash. It expected all DisplayObjects to have three properties: x, y, and rotation. Since there is no concept of a DisplayObject in the canvas API, I created a javascript object with the same interface as the Flash DisplayObject. It is the javascript DisplayObject that is also responsible for actual draw calls to the canvas.
  3. In the canvas drawing API there is no concept of separate drawing layers for DisplayObjects. The javascript version of the DisplayObject class can't be used to handle clearing graphics since it could clear a section of the canvas with another DisplayObjects graphics on it. In the demo, I haven't actually solved this issue. I've delegated the clearing of graphics to the FrameCounter object, which is admittedly a hack. One potential solution is to use separate canvas elements for each DisplayObject but that seems like a unduly large amount of DOM manipulation for this type of animation, not to mention the potential for massive performance issues. Something I'll look into tackling in a latter experiment.


Okay, okay, enough's the demo.
Add the javascript library file.


PS - Hats off to GSkinner on the initial implementation in Flash.

Todd Cullen

Todd Cullen is a founder at ReignDesign.

Leave a Reply

Your email address will not be published. Required fields are marked *

Share this post