Mar 24 2007

swfIR flicker fix

Posted by German Rumm in flash, javascript

A while ago I wrote about swfIR and the “flicker” bug it has. Several people came to that post through Google looking for a fix, so I decided to write one.

What’s the problem

When page loads, images disappear for a fraction of second before replacement. That’s kinda annoying. Go and check an example on swfIR web-site to see what I mean.

How the fixed version looks like

View fixed version

The Fix

You can download modified swfir.js here or manually change your swfir.js.

Legend:

  • Inserted lines
  • Deleted lines

swfir.js, lines 587 – 607


    /*
    Create Container Span
    */

    var span = document.createElement('span');
        if(id) span.setAttribute("id", id);
        if(className) span.className = className;
    elements[i].parentNode.insertBefore(span, elements[i]);
    // remove : span.appendChild(elements[i].parentNode.removeChild(elements[i]));

    /*
    Add the Flash
    */

    var so = new SWFObject(this.src, "swfir"+firController.getNextId(), width, height, "6", this.bgcolor);
    if(style != "") so.setAttribute('style', style);
    so.addParam('flashvars', flashvars);
    so.addParam("menu", "false");
    so.addParam("wmode", this.wmode);
    so.write(span);
           
    span.insertBefore(elements[i], span.childNodes[0]);
    elements[i].style.position = "absolute";
 

swfir.js, lines 332 – 346


    this.resize = function( id, width, height )
    {
        if(this.swfirs[id].elasticityWidth == false)
        {
            this.swfirs[id].setAttribute("width", width);
            this.swfirs[id].style.width = width+'px';
        }

        this.swfirs[id].setAttribute("height", height);
        this.swfirs[id].style.height = height+'px';
       
        if (this.swfirs[id].parentNode.firstChild.tagName.toLowerCase() == 'img') {
            this.swfirs[id].parentNode.removeChild(this.swfirs[id].parentNode.firstChild);
        }
    }

 

How it works

I used a technique called “double buffering”. It translates to “draw the graphic in the background, and replace the foreground with it only when it’s ready”.

Original chain of events was: 1. Hide the img 2. Insert flash 3. Draw flash.

The flicker occured between steps 2 and 3.

Modified version works like this: 1. Insert flash 2. Cover the flash with the img 3. Draw flash 4. Hide the img when the flash is ready.

Flicker still does occur, but since flash is under an image it’s invisible to the user.

I had no easy way of determining that flash finished loading, but I noticed that swfir.swf calls resize() method of swfirController when it’s done. So, I put the code that hides the image inside resize() method.

Suggestions

I think even better way would be to call “image hiding code” (separate function?) explicitly from the flash. Advantages:

  • if no flash – no image replacement
  • if swfir encounters an error (say, image is on another server) – no image replacement.

One Response to “swfIR flicker fix”

  1. Jeffrey Zeldman Presents : swfIR (swf Image Replacement) Says:
    Kramer auto Pingback

    [...] German Rumm’s blog said on April 12th, 2007 at 6:05 am: [...]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

captcha service