ASDocs with Flash Develop

Flash Develop is a free alternative to Flash Builder. While it may not include all of the feature of Flash Builder, it does have a nifty ASDocs generator. Follow these steps to configure the application and you’ll be good to go.

What are ASDocs?
Generated API documentation for your code. A great example is the Adobe Livedocs API. The ASDoc generator will create documentation pages based on your variables, functions and comments. Check out the specs for more info.

What is Flash Develop?
A free, light weight, IDE for developing in Flex and ActionScript. I recently installed it on my Dell mini when Flash Builder wouldn’t let me install to a thumb drive. It doesn’t have a debugger but the most recent version contains a profiler! More information about the profiler in a future post.

Why create ASDocs?
To provide documentation to anybody else that may use your code. Especially useful for re-usable components or libraries. Other people can use your code without cursing your name or asking for help every 10 minutes.

Creating ASDocs

This post assumes that you’ve already configured Flash Develop and pointed it to the Flex SDK.

Within Flash Develop, click on Tools – Flash Tools – Documentation Generator.

A screen will pop up that looks like this:
Empty Project Settings
(Click to enlarge)

Right away you’ll notice that AS2 is selected as the default compiler. If you’re still coding AS2 by choice, than you really should seek help. Let’s change that to AS3. Add a page title, generally the same as your project name and an output path, usually parallel to your src directory. Click on help in the top right corner for details on additional settings.

Now your project page should look something like this:
Project Settings Complete
(Click to enlarge)

Next, we will want to point our application to the AS3 livedocs generator. Silly, I know, especially since the application already knows where the SDK is. We still need to do it. Click on the settings tab and add the path to your bin directory within the Flex SDK.

Make sure to click ‘Save Settings’!

(Click to enlarge)

You’re ready to generate, keep in mind this could take a couple minutes depending on the size of your project. Make sure to click save project and save it to your project folder. If you close the window without saving, everything in the project tab will be lost!

Check out the end result by clicking here.

Additional Comments
On my Dell mini the compiler threw an error about a missing msvcr71.dll file. To resolve this you’ll need to copy the msvcr71.dll file from your Java bin folder to the windows/system32 folder. After that everything worked great.

Happy ASDoc generating!

Animating Feedback Widget

Using two of my existing blog posts I’ve finally put that little animated widget to use! Constructive feedback only please.

Assuming you are using a flash enabled device, click on the little feedback tab to the left. The widget could definitely use a bit of design work, but hey, I don’t claim to be a great designer. It is, however, a nice example of how simple demos can be used to quickly create functional projects. The feedback widget was creating using a combination of the Expanding Widget post and the Server Side Captcha post. I’ll improve the design over time but right now the big white box is for your comment and the little white box is for your captcha response. The captcha uses an advanced space time dimension algorithm so good luck hacking the form :)

Enjoy!

Simple Animation Performance: Flash vs HTML5

I would say the results are shocking but they aligned with my hypothesis. Flash outperforms HTML5 for simple animation used at the core of nearly every game on the internet. The basic principal of games is that the screen is refreshed on an interval x number of times per second as one or many objects move.

This is really a comparison of ActionScript vs JavaScript. They are the development languages behind Flash and HTML5. Both of them are based off of the same core ECMAScript. They both have a similar number of security vulnerabilities JavaScript (1,590) vs Flash (1,110). Both of these technologies SHOULD perform the same.

Problem:
My fan would kick into high gear every time I played a game made with the new canvas component in HTML5. Convinced the crazy fan and high CPU were due to poor development practices I decided to run a simple test. Bounce a black ball up and down at 60 FPS. The concepts used in this demo are the same at the core of almost every game. Don’t take my word for it. Open up your task manager and visit the following links:

HTML5 (JavaScript):
http://www.blackcj.com/blog/wp-content/jsdemos/BallBounce/

Flash (ActionScript):
http://www.blackcj.com/blog/wp-content/swfs/BallBounce/

Want to check out the Flash source but don’t want to pay for Adobe products? Luckily Flash Develop is available for free! So is the SDK!

Results:
These results are from my PC. I would love to see results from a MAC! Any takers? Feel free to post them in the comments section.

HTML5 (JavaScript):

Firefox – 18% CPU
Chrome – 18% CPU
IE – Doesn’t work

Flash (ActionScript):

Firefox – 3% CPU
Chrome – 3% CPU
IE – 0% CPU – This was the most surprising result

Conclusion:
If your going to build a game or do simple animation, use Objective-C or Flash. JavaScript is definitely a useful language that I wouldn’t want to go without but it needs significant help in the performance arena. I would not suggest dropping a lot of money into development for animations or games with canvas at this point. You’ll quickly find users complaining about battery life and CPU usage.

Links:
Flash Player: CPU Hog or Hot Tamale? It Depends.
“HTML5″ versus Flash: Animation Benchmarking
Flash ActionScript performance vs JavaScript (Even in 2006 ActionScript performed better than JavaScript)

*HTML5 won’t officially launch until 2012 (or later) and performance might be improved by then. I haven’t seen any information either way on performance but it’s important to point out that the HTML5 specification is still in DRAFT.

Expanding Draggable Widget

Lightboxes are overused. They take way to long to load and consume far too much screen real estate. A far better user experience can be achieved by teaming up JavaScript with ActionScript. The end result is less than 6KB of code!

**Update: The feedback widget replaced the draggable widget. Please visit this link for a demo of the draggable one.**

Before going any further, you’ve probably noticed the dark red rectangle docked to the left side of this web page. Click on it. Notice how the widget expands out smoothly. Now for the cool part, click and drag on the blue bar once the widget has expanded. Drag the widget around the screen and notice the alpha transparency of the Flash object. Imagine using this for simple forms, help support chat windows, video conferencing and more.

Cool! Let’s see some code.

JavaScript

This code works great but I’m not a JS expert so it could probably be optimized. The expand and contract code is very simple JS. A div is re-sized on contract complete and expand begin. This allows the user to select text behind the div while it is contracted. The animation is done in Flash for two reasons: it looks smoother and we don’t need any CSS trickery to get the drop shadow to work in IE. I would love to see a full JS implementation of this for comparison but it is out of my skill set. Any JS guru’s willing to give it a try?

Alternatively, the div movement was offloaded completely to JavaScript for two reasons. First, the slight lag between communication becomes quickly apparent when attempting to communicate from Flash 30 times per second. Second, changing the size of the div to full screen giving Flash complete control caused a flicker at start and end. After moving all of the movement code to JS everything performed great!

Draggable Code:

var currentLeft = 0;
var currentTop = 0;
var dragObj = new Object();
var dragging = false;

// Browser detection code removed for simplicity. 
// See full source at the bottom of this post.

function expandWidget() {
    e = document.getElementById("expandableDiv");
    e.style.width = 525 + 'px';
}

function contractWidget() {
    e = document.getElementById("expandableDiv");
    e.style.width = 50 + 'px';
}

function onMouseWheel(event) {
    if (!event) event = window.event;

    if (dragging) {
        return cancelEvent(e);
    }
    return false;
}

function startDrag(clientX, clientY) {
    var x, y;

    dragging = true;

    e = document.getElementById("expandableDiv");
    dragObj.elNode = e;

    // Get cursor position with respect to the page.
    if (browser.isIE) {
        x = clientX + currentLeft + document.documentElement.scrollLeft + document.body.scrollLeft;
        y = clientY + currentTop + document.documentElement.scrollTop + document.body.scrollTop;
    }
    if (browser.isNS) {
        x = clientX + currentLeft + window.scrollX;
        y = clientY + currentTop + window.scrollY;
    }

    // Save starting positions of cursor and element.
    dragObj.cursorStartX = x;
    dragObj.cursorStartY = y;
    dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10);
    dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10);

    if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
    if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0;

    // Capture mousemove events on the page.
    if (browser.isIE) {
        document.attachEvent("onmousemove", dragGo);
        window.event.cancelBubble = true;
        window.event.returnValue = false;
    }
    if (browser.isNS) {
        document.addEventListener("mousemove", dragGo, true);
        event.preventDefault();
    }
}

function stopDrag() {
    dragging = false;
    e = document.getElementById("expandableDiv");
    if (browser.isIE) {
        document.detachEvent("onmousemove", dragGo);
    }
    if (browser.isNS) {
        document.removeEventListener("mousemove", dragGo, true);
    }
}

function dragGo(event) {
    var x, y;

    // Get cursor position with respect to the page.
    if (browser.isIE) {
        x = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
        y = window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
    }
    if (browser.isNS) {
        x = event.clientX + window.scrollX;
        y = event.clientY + window.scrollY;
    }

    // Move drag element by the same amount the cursor has moved.
    currentLeft = (dragObj.elStartLeft + x - dragObj.cursorStartX);
    currentTop = (dragObj.elStartTop + y - dragObj.cursorStartY);
    dragObj.elNode.style.left = (dragObj.elStartLeft + x - dragObj.cursorStartX) + "px";
    dragObj.elNode.style.top = (dragObj.elStartTop + y - dragObj.cursorStartY) + "px";

    if (browser.isIE) {
        window.event.cancelBubble = true;
        window.event.returnValue = false;
    }
    if (browser.isNS) event.preventDefault();
}

ActionScript

For the ActionScript, ExternalInterface was used to communicate with JS and TweenNano was used for the animation. One key thing to point out is the offset for where the user clicked when starting a drag. The trickiest part of this example was ensuring that JS knew exactly where the window should be as the mouse moved.

private function downHandler(e:Event):void
{
	_background.alpha = 0.5;
	if (ExternalInterface.available) {
		ExternalInterface.call("startDrag", this.mouseX + 10, this.mouseY + 10);
	}						
}

private function upHandler(e:Event):void
{
	_background.alpha = 1;
	if (ExternalInterface.available) {
		ExternalInterface.call("stopDrag");
	}						
}

private function JSExpand():void
{
	if (ExternalInterface.available) {
		ExternalInterface.call("expandWidget");
	}
}

private function JSContract():void
{
	if (ExternalInterface.available) {
		ExternalInterface.call("contractWidget");
	}			
}

Live demo can be found here.

Full source code can be found here.

Next Steps
Make sure the user can’t shrink the widget off the page and allow for re-docking or snapping back to the original position. Add alternate content that would navigate to an HTML page on click if the user has JS and AS disabled. Allow positioning to be configurable via Flash vars. This widget has many potential uses. I will be populating my widget with some content soon. How could this widget benefit your site?

Resources
http://www.brainjar.com/dhtml/drag/
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/external/ExternalInterface.html