Blog

Posts Tagged ‘Flash’

Workaround for the Video.clear() Bug

Tuesday, January 26th, 2010

While building video templates recently, I had my first run-in with ActionScript 3.o’s infamous Video.clear() bug. The bug is that calling Video.clear() only removes one pixel of a video, rather than the whole video.

The common workaround for the bug is to simply remove the Video component  from the stage when the movie is complete. This solution is not robust enough for my purposes because I continue to use use the Video instance to play other movies. Also, the video templates will be used by a client to develop screens for courses, and the client might change properties of the component (name, placement, etc.) so a function that always creates a component with predetermined values is not an option either.

Below I have pasted the function I use in a custom VideoHandler class to create a duplicate Video component, clear the original Video component, and place the new on the stage.

private function fClearVideo():void
{
// Stops playing video and deletes the local copy of the video, though it may still exist in cache
_ns.close();

// There is a bug with _video.clear where it only clears 1 pixel of the video
// This bug was noted in 2008, exists in Flash Player 9 and 10, and unfortunately has not been fixed
// Duplicate the Video component
var videoDouble:Video = new Video;
videoDouble.x = _video.x;
videoDouble.y = _video.y;
videoDouble.width = _video.width;
videoDouble.height = _video.height;
videoDouble.name = _video.name;

// Remove Video instance from the stage and add the duplicate instance.
this.removeChild(_video);
_video = this.addChild(videoDouble);
}

Alternative Method to Display HTML Text in Dynamic Textfields

Wednesday, December 9th, 2009

I have been trying to figure out the best way to display HTML text in dynamic text fields for ActionScript 3.0 projects over the past six months. The best solution for Five Star is one that keeps the file size small, is versatile enough to handle different fonts with ease and adapts to different projects with little or no customization.

The solution that has evolved is a function named DisplayText, which I have copied below. The comments explain how the function works and an example call is included.

If you try implementing this solution and find it useful, if you need help or would like to enhance it, please leave a comment below.

/**
 *  Takes a string of text that may have bold and italic tags.
 *  Displays string properly in an HTML TextField by replacing the bold and italic
 *  tags with font tags.
 *  Fonts should be linked in the library.
 *  Each version (regular, bold, italic) should have its own link.
 *  If 2 versions of the font (ex. regular and italic) have the same name
 *  in the Font Symbol Properties dialog Font menu you don't need specify the italic
 *  or bold version.
 *  Example Call:
 *   var s:String = "Hi, and welcome to <b>Lesson 1:</b><i>Topic 1</i>."
 *   DisplayText( display_txt, s, 13, "Franklin Gothic Book", "Franklin Gothic Demi" );
 * @param    tf                TextField to format
 * @param    s                 Text to place.
 * @param    size              Size of text display.
 * @param    defaultFont       Regular font.
 * @param    boldFont          Optional. Bold font.
 * @param    italicFont        Optional. Italic font.
 */
 function DisplayText ( tf:TextField,
                         s:String,
                         size:Number,
                         defaultFont:String,
                         boldFont:String = "",
                         italicFont:String = "") : void
 {
     tf.htmlText = true;              // Set this to allow HTML text to be set
     tf.embedFonts = true;            // Set embed fonts to true
     tf.text = s;                     // Assign text - but not as htmlText yet

     // If a bold font is specified, replace bold tags
     if ( boldFont != "")
     {
         var boldStart:RegExp = /<b>|<B>/gi;            //    Match opening bold tags
         var boldEnd:RegExp = /<\/b>|<\/B>/gi;         //    Match ending bold tags

         tf.text = tf.text.replace( boldStart , "<font face='" + boldFont + "'>" );
        tf.text = tf.text.replace( boldEnd , "</font>" );
     }

     // If a italic font is specified, replace italic tags
     if ( italicFont != "")
     {
         var italicStart:RegExp = /<i>|<i>/gi;          //    Match opening italic tags
         var italicEnd:RegExp = /<\/i>|<\/I>/gi;        //    Match ending italic tags

         tf.text = tf.text.replace( italicStart , "<font face='" + italicFont + "'>" );
         tf.text = tf.text.replace( italicEnd , "</font>" );
     }

     // Wrap the text in a tag defining default font face and size
     tf.text = "<FONT FACE='" + defaultFont + "' SIZE='" + size + "'>" +
                tf.text + "</FONT>";
     // Assign the text
     tf.htmlText = tf.text;
 }

Porting String.Format to ActionScript

Tuesday, July 7th, 2009

One of my favorite methods in the .NET framework is the string class’s Format method. If you are unfamiliar, you can read more about it here: http://msdn.microsoft.com/en-us/library/aa331875.aspx. The .NET implementation contains numerous formatting options; however, I am only interested in the basic idea of replacing format items in a string with actual values passed to the function. This reduces the need for complex concatenations, which makes code more readable.

The ActionScript version I’ve implemented works in much the same way as its .NET counterpart. The first argument is a format string containing format items. For example, to display the current date, we may set up the following format string, “Today is {0}.” Then, we pass an array of objects to use as replacements for the format items. In our example, we would pass a new array literal with one item, [ new Date().toDateString() ]. So our entire call would look like the following:

// display today's date in the text field txtDate
txtDate.Text = StringUtils.Format( "Today is {0}." , [ new  Date().toDateString() ] );

The function will return a new string that has the {0} format item replaced with the evaluated value from the Date object. It is important to note that ALL instances of {0} will be replaced, not just the first occurrence. So the function itself is very simple, but can dramatically improve the readability of code.

I have provided the source below and a link to download StringUtils.as, which has the necessary Replace function as well. The only note I would make about the code is the use of toString() on each object in the array passed to the function. This allows calling code to pass arrays containing any type of object and omit calling toString() on each instance (provided the toString() implementation is acceptable). Hopefully you find this as useful as I have!

Source:

public static function Format( formatString:String , args:Array ) : String
{
   var result:String = formatString;
   for (var i:int = 0; i < args.length; i++)
   {
      result = Replace(result, "{" + i + "}" , args[i].toString() );
   }
   return result;
}

Download Source Files

Writing a SWF to a Web Page from SQL Server

Thursday, December 11th, 2008

We recently had a requirement to store SWF files directly in our database as a file bytes field. Our client had a need to dynamically change multiple SWF files via an administrative site. Due to the clustered server environment, storing the files in a database and pulling them out on a new request was the best option.

Uploading the file was fairly routine, but actually getting the file out of the database and embedding it in the page proved to be interesting. Not only did we need a way to create this file on the fly, but we also needed it in such a way that the browser would be able to render it as Flash content.

We created an APSX page that required a parameter “id” of the SWF we needed from the database. The files bytes are read from the database as any typical file, execute a sql server stored procedure that returns an Image Data Type containing our file bytes. Then we set the ContentType of the Response to the Multipurpose Internet Mail Extensions (MIME) type “application/x-shockwave-flash”. Finally we write the file bytes to the response stream. IIS will then send the MIME along with the file to the browser.

We initially tried to use the URL of our ASPX page directly in the object and embed tags. Instead of listing our SWF as “filename.swf”, we attempted something more along the lines of “getSwf.aspx?id=1″. A noble idea, but it lead to little more than a blank page. Our next approach was similar, but we used SWFObject to write out the Flash content instead. Again, the URL we passed to SWFObject was an ASPX page that was returning the file bytes of the SWF. Still no luck, just a blank page.

It started to look as if this might not be possible, but then we had a different idea. What if we gave Flash player a shot at rendering the file bytes? We would write our own static SWF that did nothing more than attempt to load a URL it received as a parameter. In this way, we could provide a hardcoded URL to SWFObject and rely on the Player to handle the dynamic piece of the puzzle.

In short, it worked! We wrote a quick SWF (targeted to Flash Player 7) that simply used a MovieClipLoader to load a URL into a container clip. The URL itself was an ASPX page that returned the file bytes of a SWF as stored in the database! Flash player understood the response and was able to load and render the SWF just as if we passed a direct filename with a “.swf” extension.