Flash + Fonts:W TF?! just linking to a font, no embedding…13Kb increase in swf size!?
Trying to optimize a banner ad., baffling, a single textfield, no embedded fonts, just switching to a different font has HUGE differences in the swf size. Interestingly that actually embedding the glyphs don't seem to take up as much space as I would have though. Here's a size report with a bunchof textfields on stage:
Font Name Bytes Characters
---------------------- --------- --------------
DejaVu Sans Light 28510
Linux Libertine 26852
Warnock Pro SmBd 26184
Warnock Pro 25379
Chaparral Pro 20827
Myriad Pro 17713 abcdefghijklmnopqrstuvwxyz <--very little diff.
Myriad Pro 15541
Adobe Caslon Pro 11549
Kozuka Mincho Pro EL 3809
Franklin Gothic Medium 2697
_sans 2447
Arial 2447
_serif 2335
Tahoma 1819
Verdana 1445
Abadi MT 1183
Baskerville 1158
Abadi MT Light 1082
Trebuchet MS 335
Times 319
Microsoft Sans Serif 38
Arno Pro 30
Courier New 31
Letter Gothic Std 22
Courier New 19
Sveningsson 19
Wingdings 18
Arno Pro 18
AbcPrint 18
Georgia 17
Futura 17
The goal here is to have a lightweight placeholder font, so that the runtime fonts can be loaded up once. At the moment just mentioning Myriad Pro ends up taking as much space as the font library we created earlier (!). My present guess is that the size of the library is related to the number of characters inside it, some of the doubling may be the jump from small ascii tables, to big unicode tables.
As much as I love Myriad Pro, alternates with similar spacing and weight for MyriadPro (16K), are Georgia (18bytes), Arno Pro(30B), Trebuchet (335B), Abadi MT (1K)...more than doubling in size at every step!
UPDATE:
Something very wierd is going on. In playing around with it, I was able to get one text field that had only 22Bytes and used Myriad Pro. However other fields that looked identical in the properties panel, when turned on ended up being 17Kb. I'm wondering if somehow turning on/off embedding causes this switch.
Flash: Multiple Runtime Font Sharing Embedding with only Partial Character sets: How To.
Here's another example of runtime font loading, this time using html text, multiple flavors of the font library, in two separate swf libs, one with the regular font, the other with the bold, italic, bold italic flavors. Typically these would be loaded at different times, but this example should give you the basic idea.
The multiple font lib built by FlashDevelop + Flex 3.0 as "FontLibs.swf", being output as 'MyriadProExtendedFontLibs.swf', the one we created in the previous is now being loaded as 'MyriadProRegMinLib.swf'
package{ import flash.display.Sprite;import flash.text.Font;
public class MyriadExtendedLib extends Sprite
{
[Embed(source='C:/WINDOWS/Fonts/MyriadPro-Bold.otf', fontWeight='bold', fontName='Myriad Pro', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]
public static var _MyriadProBold:Class;
[Embed(source='C:/WINDOWS/Fonts/MyriadPro-BoldIt.otf', fontWeight='bold', fontStyle='italic', fontName='Myriad Pro', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]
public static var _MyriadProItalBold:Class;
[Embed(source='C:/WINDOWS/Fonts/MyriadPro-It.otf', fontName='Myriad Pro', fontStyle='italic', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]
public static var _MyriadProItal:Class;
public function MyriadExtendedLib()
{
super();
Font.registerFont(_MyriadProBold);
Font.registerFont(_MyriadProItalBold);
Font.registerFont(_MyriadProItal);
}
}
}
And the consumer of the fonts
-
package {import flash.display.Loader;import flash.display.Sprite;
-
-
import flash.events.Event;
-
-
import flash.net.URLRequest;
-
-
import flash.text.*;
-
-
public class MultiFontLoader extends Sprite {
-
-
public function MultiFontLoader() {
-
-
loadFont("MyriadProRegMinLib.swf");
-
-
loadFont("BaskervilleRegFontLib.swf");
-
-
loadFont("MyriadProExtendedFontLibs.swf", true);
-
-
}
-
-
private function loadFont(url:String, complete:Boolean = false):void {
-
-
var loader:Loader = new Loader();
-
-
if (complete) {
-
-
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fontLoaded);
-
-
}
-
-
loader.load(new URLRequest(url));
-
-
}
-
-
private function fontLoaded(event:Event):void {
-
-
drawText();
-
-
}
-
-
public function drawText():void {
-
-
var tf:TextField = new TextField();
-
-
tf.defaultTextFormat = new TextFormat("Myriad Pro", 16, 0);
-
-
tf.embedFonts = true;
-
-
tf.antiAliasType = AntiAliasType.ADVANCED;
-
-
tf.multiline = true;
-
-
tf.autoSize = TextFieldAutoSize.LEFT;
-
-
tf.border = true;
-
-
tf.htmlText = "<p><b>Troy</b> was <b><i>here</i></b><br/> <font face='Baskerville'>Scott was</font> <i>here too</i><br/>...:;*&^% </p>";
-
-
tf.rotation = 15;
-
-
addChild(tf);
-
-
}
-
-
}
-
-
}
Flash: Runtime Font Sharing Embedding with only Partial Character sets: How To.
While not planning on it, spent most the day figuring out how to implement runtime shared fonts, while only embedding a fraction off the characters. Holy moly was this a minefield. But happily got a simple solution.
Here's the goal, I'm working on the phase 2.x of a website, and we are using several flavors of Myriad Pro to make it look great, plus a few others. However with each flavor weighing in at ~35Kb each we are loading about 200K worth of fonts (bold, italic, bold italic etc), and at present many of the pages have their own copies of the fonts (the typical evil that comes up on projects with no time), so the sight loads far more sluggish than it should. After this and the following are done, the load is down to 54kb, as only the elements needed are loaded once.
In Flash IDE (CS3) and prior selecting partial characters was easy if you only had one swf, just select from the characters in the embed button, in the properties panel. If you have character sets you use often, short cut this by creating custom character sets, with this neat approach, perhaps even with this tool However this is only really good for elements scoped inside the swf with the embedded font, no way to share them between swfs without resorting to traditional runtime shared libraries that have several issues (like bypassing preloaders all together). In AS2.0 there was a nifty hack possible to help,where a embedded font was coerced into sharing by a proxy clip that referenced it as a runtime shared library, at the preloaders convenience, but this (for me) was brittle in having font collisions, e.g. a static textfield on stage could render the approach useless, and I'm pretty sure this doesn't work anymore in AS3. UPDATE. !%!$ AS3 has the exact same issue, flash player appears to load a font in a given swf scope on a first come-first serve only once. Meaning any static or textfield anywhere on teh stage (regardless or not if any characters are embedded) will collide with whatever you load in dynamically later, rendering the dynamically loaded useless,...and any references to it. Meaning your dynamic textfields will break...not show up at all!. A possible workaround is having either the placeholder textfields with a sacrificial font (e.g. sans), or renaming the font in the embed created in a few steps to something like (Myriad Pro ->MyriadPro) and adjusting the css/etc.
For reasons unknown to me, adding a Font symbol to the library (either for use with actioncript, or runtime sharing) embeds the whole font. Needless to say, when on the web, getting every character known to mankind is not going to help your site load fast. This can be the difference of 2kb for only what you need for the preloader, to 2MB for entire international character sets. Also it can grind compile times to a halt, as every publish requires every glyph to be embedded and this is time consuming. Both seem like major oversights on the Flash IDE's design.
So oddly the best way to create fonts is to use the Flex 3.x SDK (download). For this the great and free FlashDevelop (download) will work great (if your on windows). Just follow the installation instructions, setup a new Actionscript 3, Flex 3 Project.
Create a class like the following in the 'src' directory, and in the righthand tree, right click over it and select 'always compile'
-
-
package {
-
-
import flash.display.Sprite;
-
import flash.text.Font;
-
public class MyriadProFontLib extends Sprite {
-
-
[Embed(source='C:/WINDOWS/Fonts/MyriadPro-Regular.otf', fontName='Myriad Pro', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]
-
-
public static var _MyriadPro:Class;
-
-
public function MyriadProFontLib()
-
{
-
super();
-
Font.registerFont(_MyriadPro);
-
}
-
}
-
}
Go to the Top Nav's "Project>Properties" and adjust the output file to something like "bin\FontLibs.swf"
Copy the characters you want as Ascii e.g. (missing white space)
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~©®·ˆ˜–—‘’‚“”„†‡•…‰‹›€™
goto this great unicode converter here
top left 'characters' box, then hit convert
select the output from the Unicode U+hex notation box, and paste it into this app's left side.
Copy the right side and replace the 'unicodeRange=''' in the above class.
Build the file by pressing the green play looking button. If all goes well you should see the console output
(fcsh)
Build succeeded
Done (0)
and a new FontLibs.swf in the bin folder.
You can use the excellent Action Script Viewer 6 to look at the glyphs embedded into the FontLibs.swf. This is very useful for seeing if the unicode is getting you the characters you think you are putting in. I tried several ascii to unicode convertors, and only the one linked above got it right.
Then using the tool of your choice create this class to load up the fontlib and use a dynamic textfield.
-
package {
-
-
import flash.display.Loader;
-
-
import flash.display.Sprite;
-
-
import flash.events.Event;
-
-
import flash.net.URLRequest;
-
-
import flash.text.*;
-
import flash.utils.describeType;
-
-
public class FontLoader extends Sprite {
-
-
public function FontLoader() {
-
-
loadFont("FontLibs.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 {
-
-
drawText();
-
-
}
-
-
public function drawText():void {
-
-
var tf:TextField = new TextField();
-
-
tf.defaultTextFormat = new TextFormat("Myriad Pro", 16, 0);
-
-
tf.embedFonts = true;
-
-
tf.antiAliasType = AntiAliasType.ADVANCED;
-
-
tf.autoSize = TextFieldAutoSize.LEFT;
-
-
tf.border = true;
-
tf.text = "Troy was here\nScott was here too\nblah scott...:;*&^% ";
-
tf.rotation = 15;
-
addChild(tf);
-
-
}
-
-
}
-
-
}
In decreasing order of relevance, these are some of the posts that I read to get to this point.
If characters that are embedded are funky, and your using Flex 2.0, upgrade to Flex SDK 3.x. I was originally using Flex 2.0...very dated at this point.
If your using OTF (Open Type Fonts) like Myriad Pro make sure your using Flex SDK 3.x else you might have issues...flex 2.0 is very dated at this point. Also consider using a tool like the excellent CrossFont if you're trying to use Mac Fonts.
[1] The one that helped me realize the ability to limit the unicode. The more readable one on the yahoo labs, and the authors blog with many comments. The solution he and others presented didn't work for me, and I think the solution here is cleaner.
[2] Flex 3.x Compiler comes with multiple The font transcoder doesn't always work, try another. in particular the (flash.fonts.AFEFontManager);
[3] Runtime Font Sharing For Flash CS3...[Robert's excellent article and followup] [far more verbose] , using the traditional whole-enchilda Font.
[4] Special considerations when using Japanese character sets (a) usin (b)
[5] A must read if you want a grand Q&A of embedded fonts and many quirks, (CSS specific)
[6] More details on mime-type for the font, I think this was only relevant in Flex 2.0 than Flex 3.x.
[7 ] Basics with AS3/Flex without using a library
[ 8 ] More rants on Flash CS3's lack of proper embedding, in particular with pixel fonts..Flash CS3 renames them for you.
AS3: Caching Sound, Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
Sound object is a single use item. Once it's been loaded you can't use it again, regardless if it's the same mp3 or a different one, or null, you'll get the cryptic error "Functions called in incorrect sequence"
Example: do this:
s = new Sound(req);
///do a bunch of stuff, and at some time later try to load a new mp3 in
s.load(req);
You will get
Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
For each new mp3 you need to create a new Sound object. Note that SoundChannel is like a playhead, more than one of them can be accessing the Sound data, so you can create chorus/echo effects by triggering play() multiple times at different time/offsets. Here's a sound player that cycles through 2 mp3s with no errors, and caches the results.
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.events.*;
import com.troyworks.core.persistance.CacheEvent;var mp3s:Array = ["test.mp3","BT - Satellite.mp3"];
var cache:Object = new Object();
playNext_mc.addEventListener(MouseEvent.CLICK, playSound);
var s:Sound;
var _channel:SoundChannel;function getNextAudioURL():String {
var curURL:String = mp3s.shift();
mp3s.push(curURL);
return curURL;
}
function playSound(evt:Event = null) {
var audioSwfURL:String = getNextAudioURL();
trace("***************************************************************");
trace("playSound " +audioSwfURL);
//trace(" attempting to restore " + audioSwfURL + " into AUDIO");
try {
if (_channel != null) {
//_channel.stop(); //UNCOMMENT ME TO STOP THE PREVIOUS PLAYING TRACK
//s.load(); //won't work with progressive
//s.close(); //won't work with progressive
}
if (audioSwfURL != null && cache[audioSwfURL] == null) {//////////// normal audio loading ////////////
var req:URLRequest = new URLRequest(audioSwfURL);
s = new Sound();
//speaker_mc.display_txt.text =".";
s.addEventListener(Event.COMPLETE, onSoundLoaded);
s.addEventListener(IOErrorEvent.IO_ERROR, onSoundFailedToLoad);
s.load(req);
}else{//////////// use cached audio ////////////////
trace("hitting cache");
var cevt:CacheEvent = new CacheEvent(Event.COMPLETE);
cevt.target = cache[audioSwfURL];
onSoundLoaded(cevt);
}
} catch (err:IOError) {
trace(err.toString());
} catch (err:Error) {
trace(err.toString());
}
}function onSoundFailedToLoad(Event:IOErrorEvent):void {
trace("onSoundLoaded **FAILED**");
//speaker_mc.display_txt.text = "!";
}
function onSoundLoaded(event:Event ):void {
//speaker_mc.display_txt.text = "";var localSound:Sound = event.target as Sound;
////////////// parse the key mp3 name /////////////////
//NOTE: a cleaner approach way would to be a Proxy that passes arguments along with the event, created during //the listener
var url:String = localSound.url;
var a:Number = url.lastIndexOf("/");
var b:Number = url.lastIndexOf("\\");
var c:Number = Math.max(a,b);
var url2:String = url.substr(c+1, url.length);
trace("onSoundLoaded" + url2);//////////// cache it ////////////////////////
cache[url2] = localSound;
_channel = localSound.play();
localSound.addEventListener(Event.SOUND_COMPLETE, onPlayComplete);}
function onPlayComplete(evt:Event):void {
//if has more sounds play them else, move to next slide
//content_mc.play();
}
playSound();
Caching Sounds...or anything for that matter
Once you've loaded a Sound(Bitmap etc) it's in memory so if your reusing it (e.g. Sound FX) there's no need to reload it. Here you can use a cache, using the name of the sound as a key, and a CustomEvent to mimic the loaded event, as the default Event target is readonly, so you can't mimic the call coming from the cache. The solution is to override it, and call the listeners directly if you can't redispatch using the original sound. The advantage is the loading event, don't know the difference between the real or loaded. The cache might also be used for offline/online type activities. But of course be aware you're memory useage for caching like this can get large quickly.
package com.troyworks.core.persistance {
import flash.events.*;
public class CacheEvent extends Event {private var _overriddenTarget:Object;
public function CacheEvent(type:String,bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
}
override public function get target():Object{
return _overriddenTarget;
}
public function set target(target:Object):void{
_overriddenTarget = target;
}}
}
UI: reusing flash.display.Loader and non-visible preloading
This covers how to preload images then scale/center appropriately prior to showing them.
Going Old Skool doing it Flash8 Style
In Flash8 preloading assets required all sorts of trickery to load a clip prior to resizing it, centering it and then displaying it. There were two techniques
1) loading the clip offstate
2) putting it into a nested clips, one was a container, the other a sacrificial clip. Any changes to realClip would get blown away as the new image/clip gets loaded in.
- PictureThumbnail //200x300 normally scaled down to 100x100
- loadTarget_mc
- realClip_mc
so we would do something like
realClip_mc.loadMovie("image.jpg"); //400x500
loadTarget_mc._visible = false;
In addition we'd have to do some juggling of the scale/centering of realClip to match that of the PictureThumbnail.
Flash 9 suave.
Thankfully with flash.display.Loader, and the display list there is the capability to avoid jumping through these hoops.
One of the major changes for me was wrapping my head around the flash.display.Loader object and it's relation to the display list. The idea of adding a Loader to the display list as in the Adobe example, is similar the old school approach of putting it in undesired containers, we'd really prefer getting PictureFrame.image.jpg Getting at the loaded clip is even more difficult: loader.contentLoaderInfo.content ! In addition the need to addListeners to the
configureListeners(_loader.contentLoaderInfo);
instead of the loader object directly was non-intuitive.
The nice thing is with the DisplayList there is a whole world of nonrendered visual behavior. So we can Load our clips independent, then manipulate them prior to adding them to the display list exactly where we want/expect. And then proceed to reuse the Loader for other assets (as in a sequential preloader). Here's an example, in where we can reuse the loader, and then when it's complete match it's size to an onstage Flash IDE drawn placeholder.
