Greg Walsh

A blog since 2002

Converting a web-based app from Flex (AS3) to HTML 5

Thursday December 16, 2010

Tweet

Working with my intergenerational design team at the HCIL, I designed and developed an distributed co-design tool affectionately known as DisCo (article). DisCo supports Layered Elaboration (article) which is a way groups can asychronously design iteratively while leaving previous versions intact. I developed the first three prototypes of DisCo in AS3 and and compiled with the open-source Flex compiler mxmlc. Because I was so familiar with ActionScript, I only coded the original prototypes using pure AS and did not use any of the MXML that Flex is known for which turned out to be a good thing.

In order to mentally prepare myself for my big push on my my dissertation proposal, I decided to port my research project from Flash to HTML5 to make sure it could be done before I start writing about all the things it "will" do. I was able to cut and pasted from my AS3 code to my javascript code with only minor changes. (My hardest problem to overcome was due to me renaming a file and not changing a reference to it in my code forcing me to keep reloading and re-uploading until I figured it out). My code is at about 90% of feature complete from the previous version to the new version. NOTE: I am not a computer programmer and as such, everything I write below could be the absolute wrong way to do this. I don't use an IDE for either language...I just use gEdit or BBEdit to code and Firebug to debug for both.$ I'm sure there are better more efficient ways to do this but these worked. This is mostly for my own records.

Drawing

My first step to porting a drawing app from AS3 to HTML was understanding the canvas element. The canvas element is similar to AS3's flash.display.Stage object in the way that I was able to attach event listeners. It is similar to the flash.display.Sprite object because I was able to draw "into" it. In AS3, I used the graphics keyword (graphics.lineTo, etc) in order to render graphics into my object. In HTML, I needed to define a context (eg canvas.getContext("2d")) after I created the canvas element. Once I had the context, I was able to use (almost) the same code from AS. AS3's graphics.lineStyle became context.strokeStyle and context.lineWidth. I even named my active context "graphics" so that my code worked with little editing.

Loading Data

In my original app, the swf calls to php with a URLRequest to see how many layers there are in the design. Once it gets that list as an array, it iterates through and retrieves each layer's data through another URLRequest. That way, each layer object has its own data array of graphic data. To do this in javascript, I needed to use the HTTPRequest most often associated with AJAX. Unfortunately, Javascript didn't work as smoothly as AS. AS3 kept each URLRequest separate but JS overrides each one until only the final request is processed. If you think of the DOM model, I was calling the JS requests from the same element so of course it overrode each one...I'm sure the AS3 one would have overridden each had I called them from the same object. I ended up using the solution on this page (link). You make an array of requests and check them to make sure they've all gone through. Once I did that, I was able to trigger the canvases to draw their respective data.

Saving Data

Little thing...In AS3 when you convert a nested array to a string, the brackets go with it (eg [[brush,1,10],[brush.20,10]]). In JS, they didn't and it only kept the commas. I needed to write a simple script to convert my arrays to strings and keep the brackets so it would be stored in the database in a way my loader would know how to decode.

Objects vs Scripts

AS3 is object oriented and I got spoiled using it. JS can be OO if you work really hard at it but it is so easy to not be. I have one true object in the whole bunch and the rest is just a giant set of methods called from wherever by whomever. I had typed all of my variables (mystring:String) in AS3 and found myself deleting a lot of variable types in JS. I also had scoping issues with a few variables although most things worked just by copying and pasting AS3 to my JS files.

Summary

I'm lucky most things worked. That shows the power of ECMA script. Moving forward, I need to implement straight line and ellipse tools that has live previews. I used a dynamic sprite in my AS3 app and I may need to make a new canvas for the JS, so,$ I'm not sure how my event models will change and I heard I need to manage the animation like double-buffering in Java. I'm also not sure how my text annotation tool will work either.

No matter how this turns out I think I'll have a great prototype to work with for my dissertation and I'll be moving from Flash to HTML5 for most interactive things.

Home