Thursday, December 4, 2008

Dynamically loading embedded images in AS3

Huge kudos for a post found on UltraShock that saved me today when I was on a crazy deadline to finish something:

I had recently completed a project that was built as a flash projector file. Originally the movie used external .jpg's that loaded at runtime, but to make it safer to distribute it was decided that all of the jpgs had to be embedded into the swf and loaded from there.

The actionscript stored all of the image names in an array and called them in sequence to load into a movieclip. To do this I just used a Loader() object. However when moving the assets into the swf I couldn't (quickly) find a simple way to load them dynamically anymore.

The first step was to turn each image into its own class with the filename as the class name -- so IMG_45.jpg was turned into a class (using the linkage panel) called IMG_45, etc. So far so good. But then we got stumped on how to load it dynamically. While I could have made them all movieclips, put them all on the timeline and called: this['IMG_45'] -- but that would have required that all 60 high res images be placed on the stage and probably killed performance.

In the end I had about 15 minutes to find a way to load the specific class when all I had was a the name of it -- as a string.

Anyway, some Googling found this brilliant function that solved it in 5 minutes instead:

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.getDefinitionByName;

var bitmapData:BitmapData = getBitmapData(myImg);
var bitmap:Bitmap = new Bitmap( bitmapData ); this.addChild(bitmap);

function getBitmapData( className:String ):BitmapData{
var obj:BitmapData;
var cls:Class = getClass( className );

try{
obj = new cls( 0, 0 );
}catch(err:Error){}

return obj;
}

function getClass( className:String ):Class{
return getDefinitionByName(className) as Class;
}

Awesome -- truly!!

stopAllSounds() in as3

FYI - The old stopAllSounds() method in Actionscript 2 has been replaced with the static method SoundMixer.stopAll()

You implement it this way:

import flash.media.SoundMixer;

SoundMixer.stopAll();

Tuesday, December 2, 2008

Facebook: can't next fb:name inside of a meta tag of an fb:share-button

This won't work:

<fb:share-button class="meta">

<meta name="medium" content="blog"/>

<meta name="title" content="<fb:name uid=<?php echo $userid ?> useyou=false /> found this great video"/>

<meta name="video_type" content="application/x-shockwave-flash"/>

<meta name="video_height" content="345"/>

<meta name="video_width" content="473"/>

<meta name="description" content="Cleaning the coastline"/>

<link rel="image_src" href="http://mysite.com/myimage.jpg"/>

<link rel="video_src" href="http://mysite.com/myimage.flv"/>

<link rel="target_url" href="http://mysite.com"/>

</fb:share-button>


Now you are probably wondering why I wouldn't just set the name var in php and print that instead but this was being used as the return call from ajax and I wanted to try and use the fb:name tag just like any other fb tag. But it doesn't work. So it appears that "some" fb tags can be nested but not this one (or just not in this way).

As a workaround I sent the name along with the other params in the ajax call and just built the whole string on the server instead:


<?php

$username = $_GET['username'];

$itemId = $_GET['itemId'];

$itemDescription = $_GET['itemDescription'];

$itemURL = $_GET['itemURL'];

$itemImage = $_GET['itemImage'];

$itemType = $_GET['itemType'];


if($itemType=='video'){



echo '<fb:share-button class="meta"> <meta name="medium" content="blog"/> <meta name="title" content="' . $username . ' found this great video on Baha\'i Explorer"/><meta name="video_type" content="application/x-shockwave-flash"/><meta name="video_height" content="345"/> <meta name="video_width" content="473"/> <meta name="description" content="'. $itemTitle . '"/> <link rel="image_src" href="http://i3.ytimg.com/vi/'. $itemId . '/default.jpg"/> <link rel="video_src" href="http://www.youtube.com/v/' . $itemId . '&hl=en&fs=1"/> <link rel="target_url" href="' . $itemURL .'"/> </fb:share-button>';

}

 

?>

Facebook share pod causes flash to become invisible

Another problem with Facebook and Flash playing together. Using the fb:share-button: when the user clicks it the share pod appears in IE but it also makes the flash on the page disappear. This only happens in IE. I've tried setting the fb:swf wmode param to transparent but it doesn't help. Very frustrating...

update: I thought of a really cheap (but workable) hack. I've made a screenshot of the flash app and then covered it with a 80% black tint and made a .jpg. This is used as the background of the div that surrounds the flash movie. This way, when a user clicks on the share and the flash disappears the disabled grayed out image shows instead -- making it "look" like everything is fine. Of course the state is different (different text is showing for instance) but the user is focused on the share pod anyway.

I'm not thrilled with it but it will work for the time being until I can figure out how to have flash make calls directly to the server. Perhaps I should be skipping to Facebook Connect??

Sunday, November 30, 2008

Facebook error: "Errors while loading page from application Runtime errors: URLExceptionEmpty URLs not allowed here"

I got this error while coding a canvas page:

"Errors while loading page from application Runtime errors: URLExceptionEmpty URLs not allowed here"

It turns out that I had an image tag that I wanted to start empty and then set the src at a later time using javascript:

<img id="myimg" src="" />

But the error above gets thrown when you try to leave the img src blank. So as a workaround I've placed a transparent spacer image instead and now it works fine...

Saturday, November 29, 2008

Form.submit does not work in Facebook FBJS

Just a note: Facebook apparently does not support the ability to submit a form using javascript -- or fbjs -- (form.submit). Thus a user must click something in order for it to submit a form.

This came up because I'm working on a Facebook app in Flex that needs to post items to the user's feed. The Facebook AS3 API (http://code.google.com/p/facebook-actionscript-api/) appears to no longer work completely -- or at least the google code page indicates that development has stopped on it -- and I'm getting very gun shy about developing too tightly against a Facebook API that changes too quickly. As a result, I've decided to use javascript to pass values out of Flash and into hidden form fields on the facebook canvas page. The problem is that I can't call a function from flash that can also submit the form. So it seems that the best work around will be to create a button that shows above or below the Flex app that a user can click when they want to share an video or audio clip on their feed. The form will be updated with the proper values from Flex whenever a user changes their audio or video selection. It's not the cleanest implementation but the tests so far prove that it can work...

Making sense out of Facebook feeds - Part one: Template Bundles

I'm trying to make posting content to a Facebook feed work and have run into quite a few problems finding a good tutorial that actually works. So I'm posting these notes for myself and anyone else who might find them useful:

In order to publish a item from a Facebook application to a users feed you need to follow a couple of steps:

1. Create a "Template Bundle": This is a template that contains up to three types of feed templates, a title only (one line), a title and short content (short story) or a longer amount of content (full story). The template contain "tokens" which are essentially placemarks where dynamic content will be inserted once a user actually publishes content to their feed using this template. Tokens have this format {*name-of-token*}. {*actor*} and {*target*} are two reserved tokens and if used will be replaced with the name of the facebook user {*actor*} and/or the target of the action {*target*} such as : "Joe tagged Joanie". There are additional reserved words that can't be used for token names such as "flash", "images", "mp3" and "video".

Here is an example of a php page that creates and registers a template bundle. In this example we will use the {*actor*} token and also create a another token called {*author*}:


<?php

// create the different feed templates

// one line feed template

$one_line_story = array('{*actor*} saw a great video from {*author*}!');

//short story template

$short_story = array(

'template_title' => '{*actor*} saw a great short video from {*author*}!',

'template_body' => 'Check this video out >'

);



//full story template

$full_story = array(

'template_title' => '{*actor*} saw a great full video from {*author*}!',

'template_body' => 'Check it out! I found on <a href="http://www.youtube.com">YouTube</a>: <br/>'

);



// now register the bundle

$res = $facebook->api_client->feed_registerTemplateBundle($one_line_story, $short_story, $full_story);

// this is the template bundle id

echo $res

?>



2. Once you've registered this bundle you can save the id you got in the last line:
 echo $res 
or go to the Facebook Developer "Registered Templates Console" (http://developers.facebook.com/tools.php?templates) and get the ID for the particular template you want to use later.

3. Now you are ready to set the feed.

4. Lets say that you have a canvas page where you post a number of videos from YouTube and CNN. On the page you want to allow the user to let people know which one they looked at--such as: "Bill watched a video from CNN". To do this you need to create a form on your page with a required tag fbtype="feedStory" and the action param that points to a php page that will process the feed content and post it for you:

<form fbtype="feedStory" action="http://apps.facebook.com/myapp/set-feed-item.php"> 

<select size=2 name="author">

<option value="" selected="true">Select an author</option>

<option value="CNN" > CNN </option>

<option value="YouTube"> YouTube</option>

</select>

<input type="submit" label="Submit" /> </form>


5. Now here is the php processing page:


<?php

$feedReturn = array(

'content'=> array(

'feed'=> array(

'template_id'=>100566785645,

'template_data'=> array (

'author'=>$_POST['author']

// add additional tokens here

)

)

),

'method'=>'feedStory'

);
echo json_encode($feedReturn);

 
?>


Once the user has submitted the form from the canvas page, this page will process the information and post the feed. However, this sample will only post text. While I have successfully implemented adding an image to a short story feed post, I have been unable to add flash, videos and mp3s - despite following the Facebook documentation closely. Hopefully I will be able to figure this out shortly and add to this post later...

Friday, November 28, 2008

Finally figured out how to have Flash call Javascript in Facebook!

This took some doing. My goal was to have a Flash as3 movie (built in Flex) to communicate with Javascript on a Facebook canvas page. Here are the steps (quickly):

1. On the Facebook Canvas page insert a <fb:fbjs-bridge/> tag ABOVE your embedded flash movie (very important that it is ABOVE).
2. Insert the <fb:swf /> as indicated in the Facebook docs. Facebook will automatically pass a localConnection name via flashvars into the swf (the var is called "fb_local_connection").
3. In your flash movie get the localConnection name that Facebook passed in:
private var connectionName:String = Application.application.parameters.fb_local_connection;

4. Facebook exposes the Javascript that has been placed on a Canvas page by providing the function "callFBJS" in the bridge flash movie. This function requires two arguments:

callFBJS(myFunctionName:String,myArgs:Array)


5. With this info you can make the connection and call the javascript function:

connection.send(connectionName,"callFBJS",myFunctionName,myArgs);



Here is the sample code of a AS3 Flex app that call a js function on the canvas page called: showInvite();



<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="components.*" creationComplete="init();">

<mx:Script>

<![CDATA[

import flash.net.LocalConnection;

private var connection:LocalConnection = new LocalConnection();

private var connectionName:String = "";



private function init():void{

connectionName = Application.application.parameters.fb_local_connection;

}



private function callFBJS(methodName:String,args:Array):void {

if (connectionName!=""){

connection.allowDomain("apps.facebook.com", "apps.*.facebook.com");

connection.send(connectionName,"callFBJS",methodName,args);

}

}



private function showInvite():void{

var args:Array = new Array("arg1","arg2");

callFBJS("showInvite",args);

}

]]>

</mx:Script>

<mx:Button x="40" y="10" label="click" click="showInvite()"/>

</mx:Application>




For more info on this evolving drama (Facebook changes stuff all the time it appears): http://wiki.developers.facebook.com/index.php/Fb:fbjs-bridge

Facebook and Flash -- problem with fbjs-bridge

I'm learning the hard way how much of a pain it is to develop apps for Facebook. Documentation is quite bad, there are very few good tutorials-- and they change things without saying anything.

Here is a GREAT example. I'm trying to use their fb:fwjs-bridge to allow an swf file to communicate with js on the facebnook page -- using a localConnection. But it turns out that it completely fails if you don't place the fb:fbjs-bridge tag ABOVE your own swf file tag (fb:swf). If you put it below, nothing works.

Makes NO sense but there it is.....

Sunday, November 23, 2008

Save the hassle -- code FBML in blocks

After struggling with using a series of inline fbml blocks in order to create a narrow and wide version of a profile box, I've decided to just do two different versions each surrounding each with either<fb:wide><fb:/wide> or <fb:narrow><fb:/narrow> tags. This saves having the complicated inline tags every line or so. It also allows me to use the style block since that is also inside the FBML tag.

Cannot use FBML in css style block

I'm learning a lot about facebook right now -- especially that there are not a lot of good resources whe you want to do more complex coding with it. The tutorials mostly skim the surface of the easiest integration -- or provide you wiht code that you have to deconstruct. Even the OReilly "Essential" book is a joke--it give a few pages of intro and then just provides the API in book form.

In any event, here is a css tip: you cannot use FBML is a style block. For instance, if you have a div like this:

<div class="content"></div>

and you define the style in a block:

<style>
.content{
width:400px;
}
</style>

you can't use FBML to change the property based on something like the width of the profile box it appears in:

<style>
.content{
<fb:wide> width:400px;</fb:wide>
<fb:narrow> width:100px;</fb:narrow>
}
</style>

Instead, you'll need to use inline styles --or enclose the tag itself in the fbml code:

<fb:wide> <div id="content" style="width:400px"></fb:wide>
<fb:narrow> <div id="content" style="width:100px"></fb:narrow>

Thursday, November 20, 2008

Facebook and Flash -- getting an embedded Flash app to work with getURL() or navigateToURL()

Long story short, you can't use getURL() or navigateToURL() with Flash when you embed the piece with fb:swf. The Flash security sandbox prohibits this in a flash movie loaded from a different domain. You can use an iframe but that causes other issues with Facebook. The folks at Facebook decided to resolve this by using a localConnection instead.

To use it add this FBML tag to the page where your FB:swf tag is:

fb:fbjs_bridge

I then created a util function called getURL() to remind me of the good old days. This function first checks to see if it can make the navigateToURL() directly and if not uses the lc instead. This way the same movie will work as a standalone and on Facebook too:

public static function getURL(thisURL:String):void{
var request:URLRequest = new URLRequest(thisURL);
try{
navigateToURL(request);
}catch(er:Error){
// for Facebook
var conn: LocalConnection = new LocalConnection(); ;
conn.send("callFBJS", "document.setLocation",[thisURL]);
}

}

Here is more info onthe genesis of the problem:

http://bugs.developers.facebook.com/show_bug.cgi?id=994#c28

Facebook errors: fb:redirect: redirect forbidden

I'm working on putting a flash app onto facebook and had this error when I tried to use a page in a tab:

fb:redirect: redirect forbidden by flavor TabFBMLFlavor on the profile tab.

A bit of searching revealed that you can't require ogin: $userid = $facebook->require_login();

Unless you check to see if the userid is null:

$userid = $facebook->get_profile_user();
if(is_null($userid)){
$userid = $facebook->require_login();
}

Monday, November 3, 2008

Outline around a Flash movie in Firefox -- with SWFObject

Suprisingly this one took a while to find the answer to. I embedded a flash movie using SWFObject and found that once a user clicked on the movie, a dotted line appeared around the edge of the swf (in Firefox). I tried adding "outline:none" to the css for the div but it didn't help. The only thing that worked was to add this to the javascript right after creating the swfObject:

swfobject.createCSS("#growth","outline:none");
(where growth was the name of the target div)

So here was the full code for the swfObject:

swfobject.embedSWF("web-v2.swf", "growth", "1024", "768", "9.0.124","expressInstall.swf", flashvars, params, attributes);

swfobject.createCSS("#growth","outline:none");

Monday, October 20, 2008

Dreamweaver CS3 crashes after Daylight Savings Time ends

Wow--talk about an obscure bug. I've been working with php in Dreamweaver CS3 and kept getting file errors sporadically that caused the program to crash. The problems were not present in the CS4 trial and was about to give up and reinstall CS2 in the hope that it wouldn't have the same problem.

But then I came across this technote on a discussion board: "Dreamweaver CS3 crashes after Daylight Savings Time ends" -- and it just so happens that daylight Savings Time ended in Israel a few weeks ago.

Sure, enough I applied the fix and no more crashes!!

Friday, October 17, 2008

Adobe announces inContext editor

This is a very col new service from Adobe -- the inContext Editor service allows the non-technical person to edit their website without a web designers help. :

http://labs.adobe.com/technologies/incontextediting/

I have been a big fan of Contribute -- but now Adobe has raised the bar higher by letting designers focus more on design and development and leave even simple typo fixes and changes to the client.

And its done in Flex :)

Sunday, October 12, 2008

Digest mismatch with RSL framework_3.0.0

After launching a brand new Flex app, I had a user report that they got this error when they tried to open the app:

"Digest mismatch with RSL framework_3.0.0.477.swf. Redeploy the matching RSL or relink your application with the matching library"

This very cryptic message related to the feature in Flex3 to have Runtime Sharing Libraries (or RSL's) -- essentially shared libraries of the framework so you don't have to export your swf with everything in it. This awesome feature cuts down on file size dramatically. If the user has visited another site that uses the same library it will save them having to download it again since the framework has been cached inside of Flash Player.

In any event, after some searching I found some pretty intense suggestions to fix this error but I also found this article on Adobe.com:

http://labs.adobe.com/wiki/index.php/Flex_3:Feature_Introductions:Flex_3_RSLs

which indicates that RSLs require Flash Player 9.0.60. After asking the user to update their Flash player, the problem was fixed.

Hopefully this might save another person who gets the same error and only finds very complicated solutions on Google for this error. Start with this approach and if that doesn't work you can try the others...

and good luck...

Monday, October 6, 2008

Sound problem fixed in Flashplayer 10

After finally discovering the root of the problem I was having with the Sound object (see below) I decided to try the beta for flash player 10 and found that the bug has been fixed!! So this just means that I can continue the development of the app and just let users know that the fix can be applied by installing the new player (which will no doubt be released in a very short time -- now that CS4 was announced)...

...phew... I was beginning to debate about building the player in AS2 and embedding it the Flex app -- and that would have been a major pain!

More problems with the Sound object in AS3

Well it appears that the Sound object in AS3 needs a lot more work! After lengthy trial and error (and some Googling) I have found that the Sound object works in direct proportion to the bitrate of the clip. The playback works fine but the problems come in when you want to scrub or pause the track. The target is 128KBPs. If you make sure your tracks are at that target, you'll be ok -- but anything lower cause the sound.position to set incorrectly.

In any event, this is a very significant bug. Kudos to Steven Sacks for helping me understand why I less hair this week!

http://www.stevensacks.net/2008/08/07/bug-with-sound-channel-position-and-mp3s-less-than-128kbps

Wednesday, October 1, 2008

Sound complete event problem in AS3 (with some mp3 files)

Ok, another frustrating one. It appears that the Sound.complete event in AS3 does not work properly. Here is what is happening:

I'm building an MP3 player and want to include a progress bar that allows a user to scrub the track. Since the Sound object can't tell at the beginning how long the track is until its fully loaded, I'm using the rss feed tag to initially set the duration. Once the sound has fully loaded I have an event handler that gets called by the Complete event. This usually works -- but I have found that for SOME mp3 files (not sure why its only some of them) when the event.COMPLETE fires the Sound.length shows that the sound is TWICE as long as it really is. A second later it return sthe proper value but that means I can't rely on the event to determine what the true length of the file is.

At least I know where to put the hack in (I'll probably wait a second or two and THEN sent the final duration)

Since I didn't get any other Google hits for this exact error (although others have reported errors with the Sound object--including the COMPLETE event), I thought I'd blog it.

Hope it helps somebody else...

Monday, September 22, 2008

SimpleXML

parsing XML with Flex/AS3 is a breeze but I need to do some work with php and it isn't quote as straightforward as i had hoped. In any event, the best bet seems to be to use simpleXML. And here is a pretty good tutorial:

http://debuggable.com/posts/parsing-xml-using-simplexml:480f4dfe-6a58-4a17-a133-455acbdd56cb

I'm still trying to get used to how to use custom namespaces but i'm close (i hope!)

Thursday, August 28, 2008

The future of the web

This is the most amazing thing I have seen in years:

http://labs.mozilla.com/2008/08/introducing-ubiquity/

Wednesday, August 20, 2008

Problems adding AS3 created objects to Flex Components

I have spent the better part of a day discovering that adding actionscript created UIComponents to the display list of a flex component will cause the component to not set the scrollbars properly.

Here is what I had:

1. An mx:Canvas object added to the stage using the tag
2. An AS3 class called ImageHolder that was extended from UIComponent
3. A loop to adds a series of 28 images into the Canvas, setting the x and y props so that they were spaced into rows of 4.

When I ran it, the objects would start to add properly but when it got to the bottom row of the canvas (where the rest of the images would have to be hidden inside the container) the images showed on above the canvas and then suddenly get hidden by the container -- as though they were on top of the canvas and not inside of it. In addition the scrollbar would not properly scroll to the last row of images -- essentially hiding the from view. I assume this is because the Canvas component was not recognizing that those last items were there and wouldn't resize again.

After trying a number of different approaches, I finally decided to create a custom component that was based on a canvas and add the images to it instead. Once I did this and added this Component to the Canvas it worked perfectly.

It probably says somewhere in the docs that you should use components as a building blocks instead of creating actionscript objects, but I just assumed that they would play nice together...

Tuesday, August 19, 2008

Nice data visualization for Flash

This is a pretty awesome framework:

http://flare.prefuse.org/

Wednesday, August 6, 2008

creating a browser window in a flex app

Here is a very cool way of creating a browser window -- using an iframe -- inside of flex:

http://deitte.com/archives/2006/08/finally_updated.htm

It also points out in the update why this is not the best way to go about this problem -- primarily because of accessibility (it can't be accessed by screen readers) -- but it is useful if really needed....

Tuesday, July 8, 2008

Awesome resource for css and javascript

Just another note to myself. Here is a great javascript and CSS resource:

Quirksmode.org

PHP email with attachments -- and how to do sendAndLoad in AS3

I took a bit of a break after the marathon 2 months to get this DVD ready and worked on a wordpress site -- and learned a lot about reconfiguring it to do what I really wanted. In any event, I'm back to working on the final steps of porting the Flash DVD to the Web. This has posed all sorts of Flash AS3 challenges as we are trying to make it usable for both high and low bandwidth users.

One new feature for the web version will be to allow users to email a copy of a selected photo to a friend. Of course, this meant learning how to use the AS3 version of sendAndLoad -- and also how to do file attachments in php email.

These links have come in handy for both of these:

How to do sendAndLoad in AS3 >

How to do file attachments in PHP email - option 1> | option 2 > | option 3 >

So far I've implemented the php code in option 1 and found it quite easy. I'll try the html version in option 2 if I get time. Option 3 is to PHPMailer. I'd like to try it someday but generally prefer to learn the code rather than implement a class built by someone else...

Monday, May 19, 2008

Odd behavior with E4X filtering in AS3

This one drove me nuts today and so I thought I'd better blog it. I was trying to create a function that to filter an xml file using E4X and locate a node with a specific "photoid" attribute:

First I tried to get retrieve the node with the correct id by filtering:

var myList:XMLList = pdXML..photo.(@photoid=="123");

but, it appears that unless the XMLList has more than one item it won't trace anything out when you do this:

trace(myList.toString()); //shows nothing
trace(myList); //also shows nothing


...even though the list clearly has one item in it:

trace(myList.length()); //returns 1

The only way that it will show the node attribute value is when you refer specifically to the attribute in the trace statement like this:

trace(myList.@photoid); // shows "123"

If the xmlList has more than one node it traces fine using toString(). But the thing that JUST occurred to me is that I SHOULD have used toXMLString()-- which (as I just correctly tested) traces the single node correctly. Even so, the xmlList should trace properly even without using the toString() or toXMLString() methods -- like this: trace(myList);

In any event, I'm not sure if this is a bug or a feature but it sure was a frustrating way to spend an afternoon...

Friday, May 16, 2008

Tutorials for skinning Flex components

Here is a blog posting that points to a number of tutorials on how to skin Flex components. I'm not ready to review them now but they will probably come in handy later ;-)

Click Here >

Wednesday, May 14, 2008

Bandwidth and debugging tool

Here is a GREAT tool for testing and debugging:

http://www.charlesproxy.com/

It lets you throttle your bandwidth to test how your page(or flash) works for different users -- plus it allows you to monitor the download times of various objects and the backend communication between flash and your server. VERY useful!

Monday, May 12, 2008

Playing with AS3 Drawing

I've been going through Colin Moocks' AS3 book and trying out some of the examples (along with getting distracted by trying related things). In this piece I tried to create a dynamic randomized drawing window. The colors are pulled randmly from an array, and the app randomly draws 3-9 lines to form an object and also randomly selects the alpha prop. After 6 objects are drawn it deletes the lowest one in the display list. People have been doing this kind of thing for a long time but this was fun to do with AS3:



Saturday, May 3, 2008

Testing regular expressions in flash

Awesome way to test regular expressions:

http://gskinner.com/RegExr/

Monday, April 14, 2008

Problems loading a local XML file in AIR on a Mac

I would never believe that I would curse a Mac -- and it's really not Macs fault! In order to let a user save the photos on this DVD project, I'm trying to build it with AIR and then port to Shu -- but for some reason I am unable to get an AIR file to access a local xml file from the same directory. Here is how I've been trying to do it:

var xmlLoader:URLLoader = new URLLoader();

var file:File = flash.filesystem.File.applicationDirectory;

file = file.resolvePath("my.xml");

var xmlPath:URLRequest = new URLRequest(file.url);

try {
xmlLoader.load(xmlPath);
} catch (error:Error) {
trace("Unable to load requested document.");
}


Works perfectly on Windows but I get the #2032 error on Mac. If I can't get this fixed today then I'll probably be forced to use Zinc instead...

Sunday, April 6, 2008

Loading too many photos too fast!

On this project we have to load over 200 photos to the screen before the app should start. I was using a for loop to instantiate the Loaders, but kept finding sporadic results in loading. Sometimes all the photos would come in and other times only some of them would. Anyway, although I have nothing to prove it, I think it just was too much for flash to load so many things at once, so it would drop some as needed. In any event I decided to use a timer instead to do the loading:
public function addPhotosByTimer():void{
// the photo paths are stored in an array
var photoArrayLen:int = myPhotoArray.length;
// trigger the timer only for the number of items in the array
// and add a photo every 1oth of the sec
var photoAddTimer:Timer = new Timer(100,photoArrayLen);
var j:int = 0;
photoAddTimer.addEventListener(TimerEvent.TIMER,addPhoto);
photoAddTimer.start();

function addPhoto(evt:Event):void{
var photoLoader = new Loader();
var thisPath:String = thisSectPhotoArray[j];
photoLoader.load(thisPath);
j++;
}
}
So far it seems to work fine...

Cannot create property ColorTransform on flash.geom.Transform

Ok, here was a weird one. I was trying to change the color of a movieclip at runtime -- which could be done with setRGB() in actionscript 2. So I did this to match the new AS3 approach:

import flash.geom.ColorTransform;

var myCT:ColorTransform = new ColorTransform();
myCT.color = 0x8e5823;

myMovieClip.transform.ColorTransform = myCT;
But when I run this I got this error:

"Cannot create property ColorTransform on flash.geom.Transform"

After pulling my hair out (just for a bit) I found that I had capitalized the colorTranform property of the MovieClip. Once I changed the last line to this:
myMovieClip.transform.colorTransform = myCT;
...it worked fine. But since I didn't get any Google result for that error I figured I would put this in.

Simple mistake but very annoying ;-)

Play mp3 files in AS3

Here is a method that can be called to play a an MP3 file. If there is a current file playing it stops before starting the next one. It should be noted that once you call the play() method on a Sound you cannot load another mp3 into it -- you need to create a new one.

I should probably turn this into a class to make it easier for reuse:

import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.net.URLRequest;

private var _soundChannel:SoundChannel;
private var _sound:Sound;

soundVolume = new SoundTransform();
soundVolume.volume = 1;

public function getVolume():SoundTransform{
return soundVolume;
}

public function playSound(url:String):void{
var request:URLRequest = new URLRequest(url);
if(_soundChannel!=null){
_soundChannel.stop();
_sound = null;
}
_sound = new Sound();
_sound.load(request);
_soundChannel = _sound.play();
_soundChannel.soundTransform = getVolume();
}

playSound("myfile.mp3");

Creating a toggling mute button in AS3

Here is some code to create a toggle mute button for sounds in AS3

import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.net.URLRequest;

private var muted:Boolean = false;
private var soundFactory:Sound;
private var soundClip:SoundChannel;
private var soundVolume:SoundTransform;
private var url:String = "myclip.mp3";
private var request:URLRequest = new URLRequest(url);


// create a new SoundTransform obj
soundVolume = new SoundTransform();
soundVolume.volume = 1;

// now create a new sound obj
soundFactory = new Sound();
// now load the mp3
soundFactory.load(request);
// and play it
soundClip = soundFactory.play();

// now set the volume of the clip --
//you need to do this AFTER the clip is playing
soundClip.soundTransform = soundVolume;

// here is an eventHandler that will mute and unmute the volume
private function toggleVolumeListener(evt:Event):void{
//toggle the boolean
_muted = !_muted;
if(_muted){
// first set the var for use with other sound clips
soundVolume.volume = 0;
// now reset the soundTransform obj of the soundClip
soundClip.soundTransform = soundVolume;
}else{
soundVolume.volume = 1;
// now reset the soundTransform obj of the soundClip
soundClip.soundTransform = soundVolume;
}
}

gotoAndStop in AS3

Very important changes in AS3 when trying to access objects in a movieClip timeline using gotoAndStop(). Here is a great blog entry outlining this change:

http://www.kirupa.com/forum/showpost.php?p=2113726&postcount=358

Saturday, April 5, 2008

Adobe on demand seminars

Adobes has made available a huge number of on-demand seminars on various topics. As soon as I have time I need to check some of these out:

Building Rich Internet Applications with Flex 3

Building AIR Applcations with Flash CS3

Building Collaborative Applications with Flex

Load Testing Flex Applications with WebLOAD

Flash 101: Part 3 with advanced tips/tricks


and more!




What a difference an IDE makes -- AS3 code editor that is!

I have tried a number of different code editors for Actionscript over the years and when I was working FT with Flash a few years ago had settled on SEPY. But coming back to this work again a few years later I needed to find a new editor for AS3. I loved the one in FlexBuilder but for some reason didn't think to use it for editing the AS3 code that I was working on in Flash CS3. Anyway, thanks to a blog post about code editors I tried opening
FlexBuilder3 and FlashCS3 at the same time. I now use Flexbuilder for the code and Flash to change design elements and to compile the swf and air files.

Very nice!

Friday, April 4, 2008

Copying and saving files to the desktop in an AIR app

Another thing I learned today was how to copy a file from one location to another -- while allowing the user to choose a location and name. This allows the user to select a photo in the App and save a high resolution version to their computer. Here is the class I wound up with:

package {
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.events.*;

public class FileSaver{
private var fileSaver:File;
private var fileName:String;
private var pathToFile:String;

public function FileSaver(){//empty constructor}
public function saveFile(_pathToFile:String,_fileName:String):void{
fileName = _fileName;
pathToFile = _pathToFile;
// point the browse to the desktop--the user can change it on their ow
fileSaver = File.desktopDirectory.resolvePath(fileName);
// once they select the location it calls saveData
fileSaver.addEventListener(Event.SELECT, saveData);
fileSaver.browseForSave("Choose the location to save the file");
}

private function saveData(evt:Event):void{
//first get the file to save
var copyFromFile:File =
File.applicationDirectory.resolvePath(pathToFile + fileName);
// now copy it to the location chosen above
copyFromFile.copyTo(fileSaver);
}

private function completeHandler(evt:Event):void {
//put something here so the user knows the file is saved
}
}

To use it, create an instance of the class and call the saveFile() method -- passing it the path to the file you want to copy and the name of the file itself. If you're using Shu (as mentioned in the post below) make sure that the path includes the Application directory as well.

One other thing I need to fix (and add to the class) is that if the user trys to save over an already exiting file, it crashes the app. It's too late tonight to fix that but it should be a bit easier now that I have the basics of the problem down...

Using Shu to create a standalone DVD project

Here is something that took a lot of time to learn (while using Shu to create a standalone app from an AIR project) Perhaps it will help someone else...

(Keep in mind that I am using Flash CS-3 because the instructions will differ if you are using FlexBuilder or the SDK)

The DVD app I'm working on needs to access a locally stored xml file and hundreds of photos. If you do this with AIR, you can have the installer include all of the files -- but in this case it creates an AIR file that was 150MB -- and the resulting Shu file was 200MB! Of course, the better way is to keep the files external to the exe. To do this you need to use the built-in Shu app path variable. Here are the steps to
implement it:

1. Follow the instructions in Shu to install its swc file into your Flash CS3 components directory
2. Drag an instance of the Shu component onto your stage
3. Import the Shu classes:
import com.cjt.shu.Shu;
4. Create a Shu instance:
   var shu = Shu.GetInstance();
5. Set the var to the appPath:
   var  shuAppPath:String = shu.Paths.app;
Now when you want to access anything that is outside of the flash file you need to prepend this variable to the path. So if you have an xml that resides in the same directory and would normally reference it this way:
pData.loadXML("presentation.xml");
you would do this instead:
pData.loadXML(shuAppPath + "presentation.xml");
...or if you have a photo that loads at runtime and its in the photos folder you do the same thing. Of course, if you don't do some error checking the app will compile but won't work when you run it as an AIR app -- but everything will be fine when you create and run the Shu file.

The good news is after I finally figured it all out, it works like a charm! The user can choose a photo and download it anywhere they want. I still have to try it out on MAC before I buy the program, but at this point I'm impressed.

However, it would be great if they included some simple tutorials on how to build stuff -- I almost gave up altogether because when I compiled my first Shu file from a fully working AIR app - and put the exe in the same folder, it didn't work at all. It was only because I had worked with Zinc before that I thought it might be necessary to access files using a application directory locater - rather than being able to just reference them relative to the app itself.

Opening a window fullscreen in AIR

Working in Flash CS3 (with the AIR updater) -- if you want an AIR app to open full screen:
import flash.display.StageDisplayState;

public function maximizeWindow():void{
this.stage.nativeWindow.stage.displayState =
StageDisplayState.FULL_SCREEN_INTERACTIVE;
}

Creating a standalone AIR app

For this DVD project I'm working on there is a requirement to let a user save selected photos to their computer. Flash of course does not allow this unless you host the files on a live server so I have been considering wrapping the whole thing in Zinc. At one point I considered AIR -- but the fact that the AIR runtime has to be installed before you can run an AIR app, killed that idea.

But, as luck (or Providence) might have it, I just got a RSS feed entry that talked about Shu -- which allows you to create standalone AIR apps. This could be just the ticket:

http://shu-player.com/

Wednesday, April 2, 2008

Determining the running frame rate in an Flash AS3 movie

I'm working on a DVD project that has over 200 photos in the main movie and have been having a LOT of trouble with the framerate. But I wasn't able to see what the actual running framerate was and what was causing my issues. There are lots of results in Google on "framerate in AS3" but all about how you can now dynamically change the framerate of an AS3 movie at runtime -- not how to determine the actual current framerate of a running movie.

Anyway, I did find one that was written in AS2 and with MANY thanks to TechMono, I've modified it for use in AS3. So, to pass on the favor, here it is. To set it up, create a new instance of the class and use addChild() to place it at the top level of your movie:
private var myFPS:FramesPerSecond;

myFPS = new FramesPerSecond();
addChild(myFPS);

...and you're done. The Class offers two public methods -- start() and stop() -- but it starts by default.

Here is the Class:

package {
import flash.display.Sprite;
import flash.text.*;
import flash.utils.*;
import flash.events.*;

public class FramesPerSecond extends Sprite {
private var fps_txt:TextField = new TextField();
private var m_counter:int = 1;
private var m_startTime:Number;
private var m_updateRate:int;
private var m_precision:int;
private var txtFormat:TextFormat;

public function FramesPerSecond(updateRate:Number=6,precision:Number=1) {
m_startTime = getTimer();
m_updateRate = updateRate;
m_precision = Math.pow(10, precision);
fps_txt.width =100;
fps_txt.autoSize = TextFieldAutoSize.LEFT;
fps_txt.textColor=0xFFFFFF;
fps_txt.opaqueBackground = true;
fps_txt.backgroundColor=0x000000;
txtFormat = new TextFormat("Verdana",13);
fps_txt.setTextFormat(txtFormat);
addChild(fps_txt);
start();
}

private function update(evt:Event):void {
if (m_counter == m_updateRate) {
var stopTime:Number = getTimer();
var elapsedTimeInSecs:Number = (stopTime - m_startTime) / 1000;
var fps:Number = m_updateRate / elapsedTimeInSecs;
fps = Math.floor(fps * m_precision) / m_precision;
fps_txt.text = "FPS: " + fps;
fps_txt.setTextFormat(txtFormat);
this.m_startTime = stopTime;
this.m_counter = 1;
} else {
this.m_counter++;
}
}

public function start():void{
this.addEventListener(Event.ENTER_FRAME,update);
}

public function stop():void{
this.removeEventListener(Event.ENTER_FRAME,update);
}
}
}


...if you want a good explanation of how it works, best to go back to the original creator. As for me, I am VERY happy to have this and was able to identify the frame-rate-killing function immediately ;-)

Friday, March 28, 2008

Resources for AS3

Awesome site to search for AS3 code:

http://flex-docs.com

Also here is a new printable reference doc from Adobe:

http://www.mikechambers.com/blog/2008/03/17/actionscript-3-ria-reference-guide/

Wednesday, March 26, 2008

Photoshop express

This is awesome! Adobe has released an online version of Photoshop built in Flex:

Check it out>

You can post your photos directly to Facebook, Picassa and Photobucket, but not Flickr(yet). Although Picnik has more features, it is significant since it's a major developer of a standalone software product launching into the online app world -- and proving once again that Flash can do the job.

And at the same time they one-up Microsoft's Silverlight...

Speed optimization in Actionscript 3

I'm working right now on a project that displays 200 photos on screen and allows the user to select them to see more details. It's running pretty slow right now so the next step is to optimize it to improve the performance. The first step is to read Colin Moock's section on garbage collection in Essential Actionscript 3 and secondly I found this great site that also outlines some other performance improving tips:

http://osflash.org/as3_speed_optimizations

Another great article:

http://www.tricedesigns.com/tricedesigns_home/blog/2006/09/more-on-flex-framerate-and-performance.html

Wednesday, March 5, 2008

Tuesday, March 4, 2008

Nice CSS dropdown menus

Given the choice between flash and css, I'd rather work with flash since you don't have to keep track of how browsers will display the same code differently -- but it is great to have the ability to do some things with css. So, in rebuilding www.hiddengifts.com I decided that I needed to get a good CSS dropdown menu working. I checked out a few -- including the Spry dropdown, but didn't like the way the secondary menu lined up with the first level and didn't want to dig into the code myself -- and would prefer to build it from scratch and see how the thing actually worked. Fortunately, htmldog.com has a great tutorial using suckerfish version 2 (son of suckerfish) dropdowns. Anyway, it took some playing around to get them to work but they look great in FireFox (but could use some layout tweaks in IE). Anyway, here is the current version:

http://hiddengifts.com/demo_dropdowns.html

Here is the tutorial on htmldog -- very nice step by step : http://www.htmldog.com/articles/suckerfish/dropdowns/

Sunday, March 2, 2008

My current take on Flash and Silverlight

Like so many other Flash/Flex developers I have been keeping an eye on Microsoft Silverlight. My first experience with it was last year when them launched 1.0 with much fanfare -- and I was stunned how badly Microsoft screwed it up. They demoed apps that didn't work at all and crashed multiple browsers, showed some really lame video samples and even did a prototype of their homepage that worked so badly that a few weeks later they replaced the background with a .jpg and only put a tiny Silverlight widget on top to simulate the effect they originally tried to get. I was able to quickly break every single app they showed. It was a very sad beginning for a product some were saying would be Microsoft's "Flash killer".

Now that a year has passed and Silverlight 2.0 is about to be released, it seems to be maturing and I'm happy that it has added some excitement to the RIA space. But as far as "killing" Flash, it seems to be just too far behind the curve. No doubt it will allow Microsoft developers -- who could not grasp the admittedly difficult Flash development process and never tried Flex -- to build some cool apps primarily in the RIA world. But Silverlight will probably appeal more to developers who by and large are not the most visually-savvy people, whereas Flash appealed first to creative types who wanted to build stuff that looked cool.

Just spend a few minutes at www.thefwa.com. I can't imagine how Silverlight is ever going to break into the rich internet experience world(hmmm, RIE anyone?). This space is largely populated by incredibly creative people who have figured out how to push the boundaries of Flash -- and have been doing it for over 10 years. So while Silverlight developers will make inroads in some areas, Flash/Flex has a huge lead and will keep innovating forward as Silverlight tries to catch up.

Anyway, what got me thinking about all this was a blog post from Doug McCune about Silverlight apps entitled: Where are the dope Silverlight demos?> Check it out!

Saturday, March 1, 2008

Coldfusion cfhttp Connection Failed error

OK, here is a very annoying problem that I have not found the answer for yet. Because of the JVM, Coldfusion caches DNS entries forever -- which means that if you move your server to another IP address -- even if you are setting up a new entry in your hosts file, you need to restart CF in order for the changes to be recognized by CF. I knew this already (after another annoying problem) but it still does not seem to explain the particular errorI'm dealing with. Here is the situation:

1. I am testing an app on a dev box that is set up to replicate the live server.
2. In the code CF needs to retrieve some xml that resides on the server and parse it.
3. Using cfhttp it tries to retreive the xml file, but keeps getting a Connection failed error -- but if I try to retrieve the data from the server directly, its there.
4. I checked the host file and sure enough the entry for the dev server is set properly -- I also restarted CF to handle the issue at the beginning of the post. Still no dice.

I'm out of options so at least in this particular case since I don't HAVE to get the file through http, I decided to just grab it directly using cffile and we're back in business.

The bad part is that in a day I'm going to have to test another part of the app that "requires" cfhttp, so the story is not over yet!

Thursday, February 28, 2008

Cool and surprising!


I like this one -- and don't know how much longer it will be live. But it certainly is creative:

http://producten.hema.nl/

PDF on AIR

Crash course on AIR: http://theflashblog.com/?p=342

Google Sites is launched

A new entry in the world of collaborative workspaces: http://www.webware.com/8301-1_109-9881487-2.html

Thursday, February 21, 2008

More on 3D Flash

I have never been that interested in experimenting with 3D flash -- even though people have been working with it for several years. But it there are a couple of 3D engines that are looking pretty exciting in their possibilities. Here are a few more sites/example that are worth checking out:

Using the Away3D engine:

http://www.closier.nl/playground/extrude1.html

http://www.fifastreet3.com/flash/wk/player.asp

Referencing a class function from inside of an XML object in AS2

Ok-- so this one tripped me up tonight. I'm converting an AS1 program to AS2 and thus moving functions into classes. So far so good, until I try to get a function to trigger after an XML.onLoad event:

myClass{
var myXML:XML = new XML();
myXML.onLoad = function(){
myFunction();
}
myXML.load("myXML.xml");

public myFunction ():void{
// function contents
}
}



-- but when tried to run this, I had no luck. You also can't use "this.myFunction()" either since "this" actually refers to the results that have been loaded. So, after a bit of Googling I found this Blog post from 2004:

http://www.bit-101.com/blog/?p=525

It turns out that the easiest way to fix it is to create a var inside the class that refers to "this" like so:

var myClass:Object = this;

Then you can simply run the example above and everything is hunky dory again ;-)

Very cool flash sites using papervision3D

Papervision3D is a 3D engine for Flash. Here are a few great examples of what can be done with it:

http://www.whitevoid.com/application

Even 3D video -- one word -- WOW:

http://adn.blam.be/papervision/

and a new version of pool:

http://www.markfennell.com/flash/pool/

Tuesday, February 19, 2008

Scribd launches iPaper

When I first saw Scribed about a year ago I was immediately impressed how they were using "FlashPaper" -- a flash-based alternative to PDF that Macromedia developed before being bought out by Adobe. One of my real concerns with the merger was the future of FlashPaper. Well, it appears that the popularity of Scribd attests to the value of the FlashPaper model and to further illustrate the point they have just released their own version of it in iPaper. This is simply an awesome next step. Check it out:

Wednesday, February 13, 2008

Awesome wallpapers

Here is a blog post with a great selection of desktop wallpapers >

Tuesday, February 5, 2008

Flash AS3 -- keylistener problems

Here is an odd one. Using Flash CS3 I am trying to capture keystrokes. But I have not been able to make it work when testing the movie within Flash -- the key press is only registered once and a while. Instead I find that the focus tends to go to the Flash CS3 interface itself (causing the tool bar to change items instead) So, I need to test the behavior by opening the .swf directly.

BTW, the forward and back buttons work fine--but the character keys are very buggy.

Very wierd. I must be doing SOMETHING wrong?

Thursday, January 31, 2008

Nice slideshow in Quicktime/html

This is a good example of how Quicktime can help create rich experiences as well: http://www.apple.com/aperture/profiles/stanmeyer.html

I still think that flash can do it more seemlessly but this approach is more accessible -- which is counting more and more these days ;-)

Wednesday, January 30, 2008

Thursday, January 17, 2008

The RIA world is pretty awesome

I've had about a 2 1/2 year break from FT Flash work and I have to say that a lot has happened since then -- both personally and in the Flash/web world. Personally, I've had the wonderful opportunity to learn more about server and web infrastructures including unix, apache, dns, mysql, VMware -- pretty much the works. I'm even comfortable now with command line (that's saying a lot since I only got my first computer with windows 95 -- and come from a graphics design background). I've also been able to work more with css and am thoroughly impressed by what can be done now in straight html, css and javascript that used to only be possible with flash.

But at the same time, my real love has been Flash and since 2005 A LOT has happened there as well. I had done most of my work at AETV.com in ActionScript 1 (I actually started with Flash 4 so the slash syntax was my first intro into actionscript). But since 2005 Flash has been through so many changes, from being taken over by Adobe, releasing AS2 and AS3, the maturation of Flex (and the happily lowered price) and finally the release of AIR which will allow for Flash apps on the desktop. Anyway, my life is now coming full circle and I have been able to get back into Flash -- and starting in March it will be my FT job again! In the meantime, I'm very busy learning AS3 and Flex2 as quickly as possible and have been able to complete work on the first version of a memorization tool using a bit of AS2. My goal before March is to rework it as an AS3 Flex app so that it can be ported into AIR as soon as the final release is announced.

Exciting times!

Live Documents --another flex/air app

LiveDocuments using Flex and AIR for a real office suite by ZDNet's Ryan Stewart -- Live Documents (ZDNet gallery) made a big splash when it first came out. The user interface is very similar to Office 2007 and a lot of the functionality from Office is there as well but the whole suite was created using Flex 2 so it can be accessed in the browser. Live Documents did a [...]

Babbel

Babbel: Learn a new language with a rich Internet application by ZDNet's Ryan Stewart -- Babbel is launching today and it’s a rich Internet application built in Flex that is going to help you learn a new language. Like any site now there is a bit of a social twist. Users of the site can message back and forth and study together. Currently the site supports Spanish, French, Italian, German [...]

Monday, January 14, 2008

Server 2 go

This is a great idea-- a self contained server that can run off of a CD:

Server2Go >

Saturday, January 5, 2008

Geo location of a server



Here is a handy little app for occasional use. It's a Google Map mashup that allows you to see the physical location of a server. It was useful for me today when a whois lookup failed to give enough info on who owned a server that was not working properly. This allowed me to see its physical location and thus allow a pretty good guess of who the actual owner was ands who we needed to contact to fix the issue:

http://www.geoiptool.com

Thursday, January 3, 2008

Great flash video tutorials

I have been taking advantage of some free video tutorials on Flex from www.totaltraining.com.They are really the best I have ever found and very inexpensive ($200 for the entire Adobe Web suite).

At the same time I just found this site : http://www.gotoandlearn.com/ -- which offers a series for free video tutorials for flash. Great stuff!