dOMi Preview - its Papervision, punk
Posted on , June 08, 2008 @ 14:49 CET
The past couple of days I've had alot of fun putting together a preview site for my buddy's band dOMi. They have a full-length album coming out at the end of August and we plan on building a web presence that is on par with the music, but until then we agreed that the plain ol' HTML page that was in place should be replaced.
Playing with Papervision has been on my to-do list for a long time (if you're going to the Papervision workshop at FOTB I'll see you there :) so I checked out the Great White branch (version 2.0 in alpha) because I figured why not play with the bleeding edge, I'm pretty sure my vaccines are up to date.
I know next to nothing when it comes to 3D modelling so we just tried to play with some basic primitives and see if we couldn't come up with something. The first attempt at something was this spinning plane with just the cover. Its ok, but we wanted more so we mapped the Photoshop comps of the cover onto a cube and moved things around a little bit to make a fluid layout that would scale nicely on a larger monitor but still look OK on 800x600. I quickly learned that Flex and its layout schemes had spoiled me. Then we found a way to make certain parts of the back cover be clickable with this great hack, in order to allow people to play the pre-release tracks from the track list itself.
Lastly was figuring out how to do a preloader in a pure AS3 project in FlexBuider, but thankfully and as always Keith Peters had a post that shows you exactly how do it. And just for me, arrow key listeners to make that sucka spin just because it can! :)
Anyways, tada! The dOMi preview site for Welcome to Annoying Town, out August 29th! Come to the show at John Dee!
- paulo
Vote!
Posted on Friday, May 30, 2008 @ 13:29 CET
Update (June 1, 2008): Mozilla fixed it! Sweet :)
Mike Chambers wrote yesterday about a bug in Firefox 3 for OS X that breaks KeyUp events in Flash. It looks like some developers on the Mozilla team want to leave it in and fix it later, so lets get the vote count up. Hopefully they'll get the message and fix it before the major release.
We don't want them getting lazy! :)
- paulo
Creating component instances from Strings in Flex
Posted on Thursday, May 29, 2008 @ 15:23 CET
Lets say you have a project where you have a data-set that you want to display in different ways. Also, the component that is to be used to display the data is sent over the wire from the server as a string, representing which ActionScript class to use. This is pretty simple to do in Flex by combining the powers of mx.core.ClassFactory and flash.utils.getQualifiedClassName, as shown below:
import flash.utils.getQualifiedClassName; import mx.core.ClassFactory; import com.paulofierro.components.*; // A String representing the component class to use var classToUse:String = "com.paulofierro.components.MyComponent"; // Get a reference to the component's class var classRef:Class = getDefinitionByName(classToUse) as Class; // Create factory object var factory:ClassFactory = new ClassFactory(classRef); // Create a new instance of the component var comp:* = factory.newInstance(); // And add it to stage addChild(comp);
Although this works great, the only thing I would do is create an interface that the components then have to implement. That way you can keep up the strict typing and get code hints later when you're using the component, by doing the following when creating the instance:
var comp:IComponent = factory.newInstance();
A few days ago I came across this example over at the Flex cookbook, that shows how to swap itemRenderers at runtime. This just takes it one tiny step further.
- paulo
Using FlashVars when loading a Flex app into another SWF
Posted on Monday, May 19, 2008 @ 15:47 CET
Back story
At work sometimes we create offline versions of the stuff we produce that run from a CD. To do this I normally create a wrapper SWF that loads in the main app SWF and everything is good to go. When its online we set FlashVars in the HTML page holding it using SWFObject's addVariable() method. To recreate this within the wrapper SWF I simpy populate _root with the same variables and then load in the app SWF into a MovieClip. This is a Flash 8 project (AS2) mind you, so the wrapper FLA looks like this:
_root.canHazCheese = "true";
_root.amountOfCheese = 1;
_root.flavour = "mozarella";
var loader:MovieClip = createEmptyMovieClip("loader", getNextHighestDepth());
loader.loadMovie("content/app.swf");
Then within the SWF that gets loaded in you access the FlashVars using _root.canHazCheese for example and you're done. The reason for using a wrapper SWF is that I can then easily publish it as a standalone projector from within the Flash IDE which is good enough for our purposes.
The problem
What if the app is built in Flex? Well, in AS3 you no longer have _root, and the FlashVars have moved. In Flash they're in root.loaderInfo.parameters and in Flex they're in Application.application.parameters. So now you have to find a way of adding these vars to the parameters object.
At first to avoid this I tried simply sending them in as query string parameters to the SWF, for example loading in app.swf?canHazCheese=true&amountOfCheese=1&flavour=mozarella, and this works fine when the SWF is loaded over http://. However, since this is going to run of a CD everything is loaded over file:// and the query string method doesn't work because along the way someone gets confused and thinks that the query string is part of the filename, and therefore doesn't find the file.
The solution
While testing various things in Flash (with an AS3 wrapper SWF) I found that when you load in a Flex SWF using the Loader class, the Event.INIT handler was tracing out the loader.content as an mx.managers.SystemManager object. Checking the LiveDocs I found that the document property was a reference to the document object, but loader.content.document traced out as null.
So what to do? Wait a frame of course :) So in the Event.INIT handler we set up an ENTER_FRAME handler that runs until the document property is defined, and then populate the document.parameters with the FlashVars. Phew! Anyways, check the code below:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaded);
loader.load(new URLRequest("flex-app.swf"));
addChild(loader);
function onLoaded(event:Event=null):void {
var flexSWF:MovieClip = event.target.content as MovieClip;
flexSWF.addEventListener(Event.ENTER_FRAME, checkContents);
}
function checkContents(event:Event):void {
var mc:MovieClip = event.target as MovieClip;
if(mc.document) {
mc.removeEventListener(Event.ENTER_FRAME, checkContents);
mc.document.parameters.canHazCheese = "true";
mc.document.parameters.amountOfCheese = 1;
mc.document.parameters.flavour = "mozarella";
}
}
stop();
As you know, Event.INIT fires when the SWF has been loaded in and initialized. In any case, once this is done the Flex app starts initializing and you have to wait until the application dispatches FlexEvent.APPLICATION_COMPLETE, and because we're in Flash we can't use Flex classes without mucking about with SWCs, so once again waiting a frame saves the day! :)
Note: I found that using mc.application in checkContents() works as well, but since the docs state that application is read-only I decided to use mc.document instead.
- paulo
SwfCreator 3000 v0.2 - now with swfmill support!
Posted on Wednesday, May 14, 2008 @ 13:49 CET
After playing with version 0.1 of the script for a little while we came up with few ways to make it even sexier so I spent a few hours last nite hacking together some new cool features, first and foremost swfmill support! Download the archive here, and read on for instructions.
What does it do?
The script loops overs a list of SWFs you have defined in an XML file and uses swfmill to create an asset SWF. Once that is done MTASC injects in your code along with any variables you have defined and spits out a SWF containing both. All you need to do is specify the path to the SWF and your classes and the name of your main class that starts up the app.
Variable injection explained
Before each SWF is compiled, SwfCreator modifies your main class a little by adding the variables you've defined to the _global scope. If this sounds dirty to you, I agree and you're right, BUT, to avoid polluting _global we create a single Object - you decide its name - and add all the variables as its properties.
So basically, if the global object name is Cheese, and you have a variable called clickUrl, then you can access it in your code at runtime by calling _global.Cheese.clickUrl.
Having them on _global also makes it easier to test things before you do this for multiple SWFs and then simply commenting out the block.
How do I use it? - slightly different
First you define your project properties in a file called project.xml (you can always call it something else). This file includes the following:
- a list SWFs that are going to be compiled and their desired filename
- for each SWF we have two sub nodes now,
movieandcode movieis SWFML (an XML schema that swfmill understands, more info here) that defines the properties of the file to be created such as the filename, width, height, framerate and Flash version (upto and including 8). It also defines the contents of the library, so here you define all the assets to be included which can be images, fonts or SWFs (with embedded assets within them)codedefines the path to where your classes are located (aka classpath) and the name of the main class that contains the MTASC entry path that starts up your SWF. If this is new to you, don't worry its simple - check this example over on the MTASC site. The variables that are to be included also go here
Finally you have to define the name of the object to be created on the _global scope for variable injection, and whether or not to use MTASC in strict mode (on by default).
The sample project.xml file looks like this:
A quick example
Now that you know how it all is put together, you can download the ZIP archive from here. Then:
- extract it somewhere (say the desktop)
- launch Terminal.app (/Applications/Utilities/Terminal.app)
- in the Terminal, change directory to where you extracted it. So for the desktop:
cd Desktopnow we run the script with the sampleproject.xmlfile like so:
./SwfCreator3000.pl -x example/project.xml
This will build the two sample SWFs and put them in the example/bin folder. The included sample project will show you how to embed and use movieclips (exported from within another SWF), a TrueType font (Narkism found over on FlashKit as freeware), and a PNG image. I think that should cover most bases.
Notes!
This is still an alpha version so things might break, if so just let me know. Also this has only been tested on OS X 10.5 (Leopard) with the version of Perl that ships with it (5.8.8, to check run perl -v from the Terminal). Also:
- the width/height/framerate settings now work! :)
- strict mode is now set correctly
- and finally, due to my still lacking 1337 regular expression skillz, the
main()MTASC entry point must have the opening brace on the same line and NOT be typed. Sostatic function main() {is fine,static function main():Void(and the opening brace on the next line) is not
Ok, that's it! Give me a shout if it helps you out :)
Update (16-05-2008): Version 0.2.1 fixes an issue where multiple clips and/or fonts were being output incorrectly to swfmill.
- paulo
Introducing SwfCreator3000
Posted on Tuesday, May 13, 2008 @ 11:55 CET
Update: This version is no longer in use. Check out the new version here.
A friend of mine had a problem where he had a whole bunch of SWFs that were quite similar - the only difference being certain variables and assets, though the library linkage IDs were identical (this is Flash 8 mind you). Now having used MTASC and swfmill before via FlashDevelop, we knew we could place the assets in external SWFs that get compiled in and do some code injection. Since these two are command line tools it also means its scriptable.
So I started hacking together a Perl script that does just that. It had been a while since I'd messed around with Perl but a few hours later I had something that was working but then a long, lazy weekend delayed this post :)
What does it do?
Basically the script loops over a list of SWFs you define in an XML file and compiles them with MTASC, adding in the SWFs that contain your assets and then injecting the variables you've defined. All you need to do is specify the path to the SWF and your classes and the name of your main class that starts up the app. That's it.
Variable injection?
Before each SWF is compiled, SwfCreator modifies your main class a little by adding the variables you've defined to the _global scope. If this sounds dirty to you, I agree and you're right, BUT, to avoid polluting _global we create a single Object - you decide its name - and add all the variables as its properties.
So basically, if the global object name is Cheese, and you have a variable called clickUrl, then you can access it in your code at runtime by calling _global.Cheese.clickUrl.
Having them on _global also makes it easier to test things before you do this for multiple SWFs and then simply commenting out the block.
How do I use it?
First you define your project properties in a file called project.xml (you can always call it something else). This file includes the following:
- a list SWFs that are going to be compiled. You have to define the properties of the file to be created such as the filename, width, height, framerate and Flash version (upto and including 8)
- the path to the SWF containing the assets exported in the library using a linkage ID
- the path to where your classes are located (aka classpath)
- the name of the main class that contains the MTASC entry path that starts up your SWF. If this is new to you, don't worry its simple - check this example over on the MTASC site
- the variables that are to be included
Finally you have to define the name of the object to be created on the _global scope for variable injection, and whether or not to use MTASC in strict mode (on by default).
The sample project.xml file looks like this:
A quick example
Now that you know how it all is put together, you can download the ZIP archive from here. Then:
- extract it somewhere (say the desktop)
- launch Terminal.app (/Applications/Utilities/Terminal.app)
- in the Terminal, change directory to where you extracted it. So for the desktop:
cd Desktop - now we run the script with the example project.xml file like so:
./SwfCreator3000.pl -x example/project.xml
This will build two SWFs and put them in the example/bin folder.
Notes!
This is an alpha version so things might break, if so just let me know. Also this has only been tested on OS X 10.5 (Leopard) with the version of Perl that ships with it (5.8.8, to check run perl -v from the Terminal). Also:
- for some reason the width/height/framerate seem to be ignored by MTASC when you compile in an asset SWF, but the output SWF inherits these from the asset SWF. Using
Stage.scaleMode = "noScale";andStage.align = "TL";can help with this too, and calling adding the dimensions to the SWF name for later reference such as"MySwf_400x200.swf";. - and finally, due to my lack of 1337 regular expression skillz, the
main()MTASC entry point must have the opening brace on the same line and NOT be typed. Sostatic function main() {is fine,static function main():Void(and the opening brace on the next line) is not
Future features
There are a few changes that I can see, for example allowing multiple classpaths, multiple libraries and maybe using swfmill to compile these which might help in letting the width/height/framerate settings stick. In any case, let me know if this helps you out :)
- paulo
PlanetFlash.org
Posted on Monday, April 14, 2008 @ 15:35 CET
Last week at the Flash User Group Norway meetup, Knut showed us one of his latest projects: PlanetFlash.org. So what's Planet Flash - its like MXNA, but its up™ :)
I don't visit MXNA that much simply because lately its often down or simply very slow. Anyhow, the only advantage it has over PlanetFlash is the rating (which shows the click rate), but I can live without that. Normally I live within Bloglines (the Dev:Flash and Dev:Flex folders contain the Flash bloggers I read), but sometimes its nice with something completely different.
That said, there are a few features I'd like:
- The "Blogs" list is cool to show what is being aggregated. However, it would be nice to have a link to the blog and another to the feed. If I see a name I don't recognize I'd like to visit their site instead of stare at some XML :)
- The link to the feed should be correct - for example my feed is at
http://paulofierro.com/rss.xml. Right now it just sends you on to FeedBurner because I like their service but if that changes in the future, I'd lose the people subscribed to the FeedBurner feed. Checking the<link rel="alternate" type="application/rss+xml" />tag in the<head>(which I believe most blogs provide) would get the right URL - It would be nice to able to export the list as OPML
Anyways, just nice-to-haves :) Be sure to check it out and let Knut know if what you think of it.
- paulo
Using FontForge to convert Adobe Type fonts on OS X
Posted on Monday, April 14, 2008 @ 14:34 CET
I've mentioned FontForge before, but never really explained how to use it - its really powerful and I use about 2% of its functionality, a little like how I use Photoshop probably. In any case, this is a quick recipe to converting Adobe Type fonts that have .PFM and .PFB extensions.
First we need to install it, so:
- Check if you have X11 - its under Applications/Utilities. If not, install it - located on your OS X install DVD under Xcode Developer Tools
- Download and install the FontForge package for your flavour of OS X from here. FontForge_intelmacX.4_... for Tiger, FontForge_intelmacX.5_... for Leopard.
Once you have it installed, run X11. Then from the menu select Applications > FontForge. The app starts up, you forgive the interface and find the font you want to open by locating the .PFB file or files (you can select multiple files). Once the font is opened:
- Select File > Generate Fonts
- Select the type of font you want to output. OpenType (CFF) does the job for me, but if you're use them with an app that doesn't support OTF, then TrueType is another way to go
- I turn off "Validate before saving", because there will be warnings, but this is optional
- Hit Save and FontForge will create the font files for you. My usual settings are shown in the image below.
- In the Finder, select all the new fonts and open them at the same time. FontBook is smart enough to recognize the fonts within the same family and install those at the same time which is a nice touch. This means you don't have to handle 20 different windows when installing the font
That's it! Is there a better, more efficient way to do this? Yeah, according to a Linux friend of mine you can run it from the Terminal which means you could script it if you need to convert tons of fonts. But for smaller operations this will work out quite nicely.
Will there be issues with the fonts that are converted? Maybe - I'm no fontographer, but so far this has worked fine for me :)
- paulo
Certified Flex head
Posted on Thursday, April 10, 2008 @ 17:02 CET
On a whim, I took the Adobe Flex 2 certification exam this morning and passed, weee! :)
I've been living in Flex for the past year or so and I'd been thinking about it so I checked out the practice test at the end of the official exam guide last night, and that was the final push. Signed up with PearsonVUE, dropped the $150 (which is not that much now that the dollar is under NOK 5, WTF?) and that was that.
The Java related questions took longer to answer since I only have experience integrating Flex apps with AMF and XML-based services so far, but it was ok all in all. Once you're familiar with a few of the APIs you kinda know the structure of things. So playing with Flex and reading its Bible seemed to be enough, which was the same strategy I followed for the Flash exam two years ago.
One thing I found curious, since English isn't the official language in Norway you get an extra 30 minutes to complete the exam. Tanks!
- paulo
Loading SWFs exported from Illustrator CS3 as MovieClips
Posted on Wednesday, April 09, 2008 @ 14:07 CET
Earlier Chris showed me an issue with Illustrator CS3 I hadn't come across. Basically exporting artwork to SWF for Flash Player 9 works fine, but (unexpectedly, at least for me) the resulting SWF is seen as a AVM1Movie when it gets loaded in to another SWF.
If this is an issue, then this AVM2Loader class should be able to help out. You use it just like the standard Loader class, and it hacks AVM1 movies to AVM2, though apparently there's an issue with audio). Sample code follows:
import net.fladdict.display.AVM2Loader;
var loader:AVM2Loader = new AVM2Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("art.swf"));
addChild(loader);
function onLoaded(event:Event):void {
var info:LoaderInfo = event.target as LoaderInfo;
trace(info.content);
}
There is one little gotcha when exporting as a SWF in Illustrator. You have to use the "File > Save for Web & Devices" dialog. There you have to pick SWF as the format, Flash Player 9 as the output type and then either "AI File to SWF File" or "Layers to SWF Frames". Both work fine and trace out [object MovieClip] once loaded in.
What doesn't work for some reason is using "File > Export" and choosing SWF as the format and Flash Player 9 as the output type. Loading a SWF exported in this manner always traces out [object AVM1Movie]. Weird.
- paulo




