Archive
You are currently browsing the archives for the Flex category.
By scott
Google defines Thermo as “Two bars or wires of dissimilar metals joined at one extremity which Couple develop a current (thermoelectric current) when heated.” I define it as a major accomplishment for Adobe that is reinventing the term “Deseloper“. Aral Balkan has posted videos from the sneak peak at Max, too cool.
This is a very early sneak peak, possibly even some smoke and mirrors, but still, Adobe has hit the nail on the head and may have finally beat the Flex Project workflow issues. Watching these videos do bring up a few questions.
Are Thermo projects bound to the original assets? If the developer are working on a project together and the designer changes something in the design will Thermo automatically update the MXML. Obviously within reason, but say the designer moved the Favorites album list above the top list. Whould Thermo recognize this and make the change without the developer intervention?
All of the styles appear to be inline in the demo, can they be extracted into CSS for runtime styling? For larger applications this is mandatory for projects that are multilingual or are available under multiple brands.
What about working the other way? Open MXML in Photoshop? I don’t know how many times I have had designers take a screengrab of something I am working on, hack it apart in Photoshop just to show me what they want. Obviously they could do some of this in Thermo but I doubt Thermo will have every tool that is available in Photoshop and if it is a quick change a designer doesn’t need to learn Thermo, they can make the change, hit Save and the workflow isn’t interupted. This would also allow designers to skin existing components or even a prototype that a developer whipped together to show a concept.
With other WYSIWYG development tools the code output is usually something I wouldn’t want to hang on my fridge. MXML is pretty clean but there are optimizations that can be applied to ensure quicker compilation and easier access via Actionscript. I hope this will be considered. In the end it is all compiled so the output is usually not an issue but as a developer I have opened many files a designer has created with a WYSIWYG applications and have almost fallen out of my chair.
I am sure I will have more questions as I let this sink in. Coming from a design/creative background developer/designer workflows are something I have worked on at most companies I have worked at. I think this is a huge step in the right direction. As long as Adobe doesn’t create a visual tool for creating business logic my job will be secure when Thermo hits the market
By scott
Well it says a lot about Silverlight when Microsoft is still rolling out Flash sites (only targeting Flash Player 8, AS3 must be too tough for them
. I know Silverlight is still in beta and obviously not ready for primetime, but I still find it a some what humorous, maybe you will too, maybe not. I am sure I will get flamed for this post, but isn’t that part of the fun of having a blog? http://www.syncmyride.com
I will admit they have almost implemented a nice SEO (Search Engine Optimized) Flash site. If you view the source you will notice all of the content is written in xhtml, the swf then parses that same xhtml and uses it as its datasource. I said “almost implemented a nice SEO’d Flash site” because if you turn off javascript the content is not displayed. Certain Search Engines will still parse the mark-up but others won’t. They should of made the site fail more gracefully and display the raw XHTML for those Search Engines who ignore javascript like Google.
As a side note, another thing I found interesting is they show an image of an iPod on the site next to their (crappy) Zune player. Understandable I guess since iPod is the number one portable music player. Microsoft isn’t going to deny that.
By scott
A few months ago I blogged about a new Flash Detection JavaScript library that a friend and colleague of mine over at FeatureBlend.com created. Well, Carl has just released a new version with some pretty cool additions. Below are his words to the Flash community. Take a look and let him know what you think by leaving a comment. Hello Flash Community,
I am pleased to announce the latest updates for the JavaScript Flash Detection (Flash Detect) and JavaScript Flash HTML Generator (Flash TML) libraries.
The most notable changes are YUI namespace support (YAHOO.util.FlashDetect), JSMin version, JSLint cleanse, pattern changes and a few other goodies.
Hope you all enjoy! Carl
If you like what you see make sure to Digg these libraries.
Digg the JavaScript Flash Detection Library (Flash Detect)
Digg the JavaScript Flash HTML Generator Library (Flash TML)
By scott
Well this will probably be my last posting that announces something my team (Yahoo! Flash Platform) at Yahoo has launched. From now on it will be my former team as I am leaving to work for Disney on Friday. This week we launched three very exciting things. The new Yahoo! Flash Platform blog (http://www.yswfblog.com), the new and improved Yahoo! Flash Development Center (http://developer.yahoo.com/flash) and our new Astra Flash Components. The Astra Library is our collection of Flash and Flex components, libraries and toolkits. In this inaugural release, ASTRA contains five UI components that complement the existing set provided with Flash CS3. The new UI components are: Tree, Menu, TabBar, AutoComplete, and Charts. ASTRA is open-source under the BSD license, and follows an approach similar to the very popular YUI Library. Keep an eye on the ASTRA library, I know first hand that there are some very cool things to come.
By scott
Well, pulled a few more hairs out today. Hard to believe I have any left. I am working on a multi-lingual application that needs embeded fonts. As most of you know, loading every character in a given fontset equates to one big ass swf. For example, if you want to embed a regular and bold Japanese font you’re looking at approx. 13 megs, and depending on the quality of the font you could be close to 20 megs. That’s a lot of font. In an ideal world the Flash Player would allow for dynamic runtime shared font libraries that allow for only a subset of characters to be embeded.
In AS2 there were a few ways (hacks) to load font libraries at runtime. Unfortunately none of the AS2 hacks work in Flash CS3 using AS3. However, there is an answer. In Flex you can embed fonts at compile time using the [Embed] metadata tag in your Actionscript. And the best part is you can use the unicodeRange attribute to define a subset of characters you want to embed. Below is a class I created that compiles a swf that contains all Latin I characters in the Arial font.
package {
import flash.display.Sprite;
public class _Arial extends Sprite {
[Embed(source='C:/WINDOWS/Fonts/ARIAL.TTF', fontName='_Arial', unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E')]
public static var _Arial:Class;
}
}
A couple things to point out here. The fontName attribute value can not be the same name as a device font. If I were to change my code to use fontName=’Arial’ the compiler throws the following warning “the embedded font ‘Arial’ may shadow a device font of the same name. Use fontName to alias the font to a different name”. To get around this I simply added an underscore before the name. From this point on you must reference the _Arial in your TextFormats or CSS. Now if you compile that it will create a swf named _Arial.swf.
Ok, great, now what? Well, now you have to load the font into the application. Here is a sample class that loads in the font and displays some rotated text just to prove that it is embeded.
package {
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.text.*;
public class FontLoader extends Sprite {
public function FontLoader() {
loadFont("_Arial.swf");
}
private function loadFont(url:String):void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fontLoaded);
loader.load(new URLRequest(url));
}
private function fontLoaded(event:Event):void {
var FontLibrary:Class = event.target.applicationDomain.getDefinition("_Arial") as Class;
Font.registerFont(FontLibrary._Arial);
drawText();
}
public function drawText():void {
var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat("_Arial", 16, 0);
tf.embedFonts = true;
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.border = true;
tf.text = "Scott was here\nScott was here too\nblah scott...:;*&^% ";
tf.rotation = 15;
addChild(tf);
}
}
}
And there you have it. Run time embeded fonts. The key lines to look at here are
var FontLibrary:Class = event.target.applicationDomain.getDefinition("_Arial") as Class;
The getDefinition method returns a reference to the _Arial class loaded in through the swf (event.target). The next line:
Font.registerFont(FontLibrary._Arial);
registers the loaded in _Arial font in the global font list. If you were to trace out the results of Font.enumerateFonts() you will now see _Arial at the top of the list.
Now lets say your site was in a few different languages you may add the following line to the FontLoader constructor to load language specific fonts at runtime.
public function FontLoader() {
var langManager:LanguageManager = LanguageManager.getInstance();
var langID:String = langManager.getLanguageCode(); //returns jp
loadFont(langID + "_Arial.swf");
}
Instead of loading in _Arial.swf the application will load in jp_Arial.swf. jp_Arial.swf would be another generated font swf like the _Arial example above but this time the unicodeRange would only include the Japanese fonts you need. All you have to do now is create a CSS file and fonts for each language, store the proper language code somewhere within the application and use that language code when loading your CSS files and fonts.
You may not know this but Adobe has supplied us with sample unicodeRanges in the following file “\Applications\Adobe\Flex Builder 2\Flex SDK 2\frameworks\flash-unicode-table.xml”. You can either use one of the supplied ranges or create your own. You may only need to embed a few characters, if so just list the unicode values of the characters you want each seperated by a comma.
Sounds pretty straight forward eh? Or is it????
In doing this I ran into a huge bug using Flex Builder to generate the font swfs. When I was experimenting with the unicodeRanges my compiled versions did not contain the proper character ranges that I specified. For example I would define a range that only contained Uppercase characters. In my test font loading app I would only see numbers. Only if I removed the unicodeRange attribute would I see all my characters. This led me to believe that Adobe had documented something that really wasn’t part of the compiler. I tried deleting files, I was checking timestamps, nothing. Then I tried to clean my project before compiling (In FlexBuilder select Project > Clean). It worked! The subset of characters I defined in my unicodeRange only loaded into my test app. YAY! Then I tried switching the unicodeRange again. DOH! nothing. Cleaned project again and BINGO!
Lesson learned: Whenever you change your unicodeRange clean your project before you compile or else your change may not be compiled properly.
I haven’t tried this in Flex 3 yet to see if the bug has been addressed. I did look at the Flex 3 bug system and didn’t see it listed. Either it has been fixed or no one has run into this issue yet. It is pretty obscure I guess.
By scott
A friend and colleague of mine Carl Yestrau just released a few Javascript Flash utilities. Check them out and let him know what you think. “I am happy to share with the Flash community a series of JavaScript Flash utilities. All are freely available under the BSD license. A detailed set of supporting documentation is available online.
JavaScript Flash Detection Library (Flash Detect)
A JavaScript library designed to simplify the process of detecting if the Flash Player is installed in a Web Browser. Major, minor and revision version information is made available in the API.
JavaScript Flash HTML Generator Library (Flash TML)
A JavaScript library designed to simplify the process of generating the required HTML for adding a Flash movie to a web document. Follows a standards compliant approach to markup generation using the object element.
I hope these libraries serve you well!”
By scott
So how’s this for enterprise level Flex applications. Yahoo! Messenger launched their beta version of it’s web-based Flex Messenger application today. Currently the beta is only available in select parts of the world, rest of the world check back soon. Congratulations to all involved.
The Messenger desktop application already has hundreds of millions of users, not only is this a huge win for Flex but it is a huge win for increasing the penetration rates of Flash Player 9 which are already at 84%.
This is just the beginning, stay tuned to see what else Yahoo! has up their sleeves.
Take that Silverlight
By scott
Adobe has announced that they are planning, over the next year, to open source the Flex SDK. Using the Mozilla Public License developers will now be able to contribute and enhance the Flex SDK including the Flex framework classes, the Flex components, the Actionscript debugger, the Actionscript 3 compilers (including the mxmls and compc compilers).
Starting in June 2007 Adobe will be posting daily builds of the Flex SDK and providing open access to a bug database online. In December of 2007 after the release of “Moxie” (Flex 3) Adobe will be posting all software assets into a public Subversion repository for public access.
What this means is development models and methods can now be drastically improved or invented. If you want to develop a Flex app using Rails, go for it. If you want to use .NET to build your Flex app, be Adobe’s guest. What this doesn’t mean is open source of the Flash Player, nor should it be (IMO) open sourced. While you are still limited to the capabilities of the Flash Player, your development process is now not limited to the existing SDK. In fact, any software developer can now make their own IDE, Flex Builder and Flash CS3 need not apply.
Flex has seen extraordinary growth in the past 6 months. Enterprise applications are popping up all the time. And with the launch of Silverlight (worst name ever by the way) the RIA arena just got a little more crowded. Personally, I feel that opening up the SDK will help attract a whole other breed of developers, ones that feel tied down to a corporate development environment. For the same reasons developers were staying away from .Net in its early day, they are staying away from Flex. Corporate controlled development environments and languages are always limited to the limits of the compiler, languages, and/or authoring environments. Back in the day, the open source arena exploded with the likes of PHP, Apache, Tomcat, etc. all open sourced and equally as powerful (or more so in my eyes). Suddenly .Net or Java was limited to developers or companies with very deep pockets. Open sourcing has worked for PHP and it is the reason it wasn’t gobbled up by corporate backed languages such as .Net or Java, <sarcascm>take a look around, you may notice a few PHP sites on the good old interweb.</sarcascm>.
Will Flex be the next PHP? Will the community take Flex development to the next level? Will Flex development now be the defacto when it comes to RIA, is it already? No one knows, only time will tell. A colleague of mine just had an interesting quote. “There are no open source millionaires.” I don’t think Adobe cares about that, that’s Microsofts attitude. Adobe just wants to provide the best possible solutions for their customers. They’ll keep making money from products like Photoshop
By scott
I have had many people request that I post the code to my ExternalInterfaceBuffer class that I made reference to in my ExternalInterface…HELP posting. This code is part of the Yahoo Maps AS3 Communication Kit that I wrote and can be downloaded from the Yahoo! Flash Developer Network. As a bonus you will also get some other very cool Yahoo! AS3 API wrappers, Search, Answers, Weather, and Upcoming.org. To make a long story short, the issue I noticed was some of my ExternalInterface calls were getting dropped. I did a boat load of debugging, and discovered it was actually the browser script engines overloading and dropping the calls. So I wrote a singleton class that queues up all the ExternalInterface calls and sends them one at a time in 50 second intervals. One thing I noticed, 50 second intervals works fine with Actionscript 3, Actionscript 2 is a lot slower so I had to slow it down to 100 miliseconds or else I was running into the same issues, just not as often.
/*
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.2.0
*/
package com.yahoo.webapis.maps.utils {
import flash.external.ExternalInterface;
import flash.utils.setInterval;
import flash.utils.clearInterval;
/**
* Utility to buffer outgoing ExternalInterface calls. Simoltaneous
* calls get dropped if they aren't buffered. It seems both Firefox and
* IE's script engine gets overloaded and either drops calls or
* throws a javascript error. This buffer ensures the script engines
* only get one call at a time.
*
* @langversion ActionScript 3.0
* @playerversion Flash 9
* @author Scott Morgan 02/25/2007
*
* @see flash.external.ExternalInterface
*/
public class ExternalInterfaceBuffer {
/**
* @private
* A singleton class that is accessed by almost all classes in this
* communication kit. This static variable gives access to this class
* ensuring there is only ever one instance of it.
*
*/
private static var instance:ExternalInterfaceBuffer = new ExternalInterfaceBuffer();
/**
* @private
* An array of methods waiting in the queue to be called. Once they
* are called they are removed from the array.
*
*/
private var methodQueue:Array = new Array();
/**
* @private
* Access to the interval that runs while the methods are being called.
* When all methods in the queue are called this variable is used to
* clear the interval.
*
*/
private var methodCallInterval:Number;
/**
* Constructor
* If an instance of this class already exists an error message is thrown
* informing that this class should only be accessed through the getInstance()
* method.
*
* @see com.yahoo.webapis.maps.utils.ExternalInterface.getInstance()
*/
public function ExternalInterfaceBuffer() {
if( instance ) throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
/**
* @public
* This static method is what makes this class a singleton, it ensures that only
* one instance of this class is instantiated.
*
*/
public static function getInstance():ExternalInterfaceBuffer {
return instance;
}
/**
* @public
* Method used to add calls to the methodQueue array. If the length of the methodQueue
* array is greater than 0 the methodChurn interval is kicked off and runs every 50
* milliseconds until the methodQueue's length is 0 at which point the interval is
* cleared.
*
* @param obj and object containing a method string, and a data
* object. The method string is the method the ExternalInterface will
* call and the data object is the object that will be passed to the
* calling method as an argument.
*/
public function addCall(obj:Object):void {
methodQueue.push(obj);
if (isNaN(methodCallInterval) || methodCallInterval == 0) {
methodCallInterval = setInterval(methodChurn, 50);
}
}
/**
* @private
* This method is called every 50 milliseconds until the methodQueue array is empty.
* This method sends the first method listed in the methodQueue array to the
* ExternalInterface.call method.
*
* @see flash.external.ExternalInterface.call
*/
private function methodChurn():void {
if (methodQueue[0].method != undefined && methodQueue[0].method != null) {
ExternalInterface.call(methodQueue[0].method, methodQueue[0].data);
}
methodQueue.shift();
if (methodQueue.length == 0) {
clearInterval(methodCallInterval);
methodCallInterval = undefined;
}
}
}
}
Pretty straightforward stuff. Ok, that’s great, now how do you use it. Simple, one line of code, well two because you have to instantiate the class.
First you have to remember to import the class
import com.yahoo.webapis.maps.utils.ExternalInterfaceBuffer
Then you have to instantiate, you may choose to write one line of code to instantiate the class and call the addCall method in one line. I was used this class multiple times in the class so I instantiated it once and made reference to it with a variable scoped to the class.
private var EIBuffer:ExternalInterfaceBuffer = ExternalInterfaceBuffer.getInstance();
And lastly, add your call to the queue by calling the public addCall method. This method expects an object containing a String containing the method name and an encapsulated data object that contains the arguments you want to pass along to the method being called via the ExternalInterface.
EIBuffer.addCall({method:"myJavascriptMethod", data:{argA:'blah', argB:'merp', argC:'DOH'}});
That’s it, I know I could of made it a bit more elegant but it does everything I needed at the time. Plus it’s open source, now the world can all join in and make it perfect
Enjoy!
By scott
Today at work we ran into another flash player / browser inconsistency. When using MovieClipLoader to load an external asset, the onLoadError event doesn’t fire in Firefox when trying to load an asset from a non-existent domain. In fact, the onLoadStart event doesn’t even fire. The other MovieClipLoader events don’t fire but they shouldn’t, there isn’t any progress and the load never reaches completion or initialization.If you attempt to load a non-existent asset from a valid domain the onLoadError event fires fine in Firefox. In IE and Safari the onLoadError event fires in both scenarios. These are the only browsers I tested but I would be interested in seeing what happens in the others.
So let me break it down. This code doesn’t fire the onLoadError event in Firefox. It just fails silently:
var mLoader:MovieClipLoader = new MovieClipLoader();
var mObj:Object = new Object();
mObj.onLoadError = function(ev:Object):Void {
getURL('javascript:alert("onLoadError")');
}
mLoader.addListener(mObj);
mLoader.loadClip('http://kaljdflkasjdf.com/image.jpg', this);
However, this code and domain do fire the onLoadError event.
var mLoader:MovieClipLoader = new MovieClipLoader();
var mObj:Object = new Object();
mObj.onLoadError = function(ev:Object):Void {
getURL('javascript:alert("onLoadError")');
}
mLoader.addListener(mObj);
mLoader.loadClip('http://www.scottgmorgan.com/image.jpg', this);
Thought I would share this knowledge with the world. Last thing I want is others pulling out as much hair as I do