The Ultimate Guide to swfIR Image Replacement

Published Sunday, November 9, 2008 @ 8:43 am • 8 Responses

[ Screenshot: Example Photo Styled with swfIR ] In this ultimate guide to swfIR, you will learn how to use swfIR to replace your ordinary images with richer, stylized graphics. swfIR enables efficient, practical and scalable application of drop-shadows, rounded corners, and even image rotation to any number of specified images throughout your site. From concept and application to examples and recipes, this guide covers everything you need for successful swfIR implementation.

The Challenge..

There are many ways to enhance the visual presentation of your images. Popular visual effects include rounded corners, drop shadows, and image rotation. To achieve these effects, designers often use either CSS, direct image manipulation, or some combination thereof. CSS may possess limited ability to round image borders in certain browsers, but for drop shadows and image rotation, designers must either modify each image individually, or rely upon convoluted techniques employing additional graphics and CSS to get the job done. This may be suitable for a single header graphic, but for any significant number of images, hand-editing each one in Photoshop with the desired visual effect is neither efficient, practical, nor scalable.

The Solution..

Fortunately, JavaScript provides a far better solution via the outstanding swfIR method. Thanks to the work of Jon Aldinger, Mark Huot, and Dan Mall, swfIR (swf Image replacement) provides designers an efficient, practical and scalable method of applying a flexible assortment of visual effects to any number of images. swfIR works by uniting the magical powers of JavaScript and Flash to dynamically stylize all specified images within all associated web pages. The JavaScript relies upon a modified, integrated version of Geoff Stearns’ SWFObject and is completely unobtrusive in its application. swfIR enables strict compliance with standards-based web design through progressive enhancement and graceful degradation.

The Process..

Once implemented, swfIR performs the following actions:

  • Identifies all specified/targeted images on the web page
  • Applies specified styles to all targeted images via Flash
  • Replaces original <img> elements with processed graphics

Each replaced image is enclosed within a dynamically applied <span> element. Further, the id or class attribute associated with each replaced image is replicated on the corresponding <span> element, thereby providing hooks for additional CSS styles. To demonstrate this transformation, here is an example showing the image markup before swfIR processing:

<img id="season" src="http://domain.tld/path/image.png" alt="Winter Scene" />

..and here is how the markup looks after swfIR processing:

<span id="season" class="swfir">
	[ replaced image; code varies by browser ]
</span>

As you can see, the code within the <span> element will vary according to specific browser types. Also notice the how the id is transferred to the <span> element itself; for replaced images identified via class attribute, the class name is transferred instead.

Application

One of the great things about swfIR is the ease of typical implementations, and the flexibility of more elaborate, custom applications. Although knowledge of JavaScript and Flash is certainly beneficial, it is by no means necessary to get swfIR up and running on your site. Here’s how to do it in four easy steps (well, okay, three easy steps and one step that requires a little thought):

1. Download swfIR!
Go to the official swfIR website and download a copy of swfIR (currently less than 12 KB zipped)
2. Upload swfIR!
Upload the two files, swfir.js and swfir.swf, into the same directory on your server (save the readme file for future reference). If these two files aren’t in the same directory, you will need to edit the src parameter, as described in the “Important Notes” section (below).
3. Include the JavaScript
Place the following code within the <head> region of your (X)HTML document (remember to specify the correct path!):
<script type="text/javascript" src="http://domain.tld/path/swfir.js"></script>
4. Specify the Styles
In this step, you specify the various styles that are applied to your target images. This step requires a bit of explaining, so we will go ahead and discuss it in detail in the next section. For those of you already familiar with this process, here is a quick, “copy-&-paste” example to get you going:
<script type="text/javascript">
	// applies a big fat white border 
	window.onload = function() {
		var sir = new swfir();
		sir.specify("border-width", "25");
		sir.specify("border-color", "fff");
		sir.swap("#example");
	}
</script>

Customization

Once you have uploaded the swfIR files to your server and included them as described in the previous section, you are ready to custom the script by specifying the various image styles. Begin by placing the following code just before the closing </body> tag of your web page 1:

<script type="text/javascript">
	window.onload = function() {
		var sir = new swfir();



	}
</script>

Then, the desired style parameters are inserted between the var sir = new swfir(); and the closing bracket. Here is the general format for each of the currently available parameters (listed below):

sir.specify([parameter], [value]);

Here is a list of available swfIR parameters and their associated value types:

border-radius    = number
border-width     = number
border-color     = color   (e.g., #fff)

shadow-color     = color   (e.g., #fff)
shadow-quality   = number  (between 0 - 1)
shadow-alpha     = number  (between 0 - 100)
shadow-blur	 = number
shadow-blur-x    = number
shadow-blur-y    = number
shadow-strength  = number
shadow-offset    = number
shadow-angle     = number
shadow-inner     = boolean (true or false)
shadow-knockout  = boolean (true or false)
shadow-hide      = boolean (true or false)

rotate           = number  (between -359 - 359)
overflow         = string  ('expand-x', 'expand-y', or 'fit')
elasticity       = string  ('true'), number (pixel-to-em ratio)
src              = string  (path to your swf file, if not standard)
wmode            = string  ('opaque', 'transparent', etc.)
link             = string  (e.g., http://www.swfir.com/)

So, let’s say that we want to add a 25-pixel white border to an image with an id of #example. After determining the required parameters from the list, our style-specification code would now look like this:

<script type="text/javascript">
	window.onload = function() {
		var sir = new swfir();
		sir.specify("border-width", "25");
		sir.specify("border-color", "fff");
		sir.swap("#example");
	}
</script>

In addition to the two specified style parameters, we have also added the required swap() method to indicate exactly our target image(s), namely:

sir.swap("#example");

Here we are targeting an image with an id of “example”. Of course, we may also target an entire class of images by including a swap() method such as:

sir.swap(".example");

Technically, the swap() method accepts any valid CSS selector. So, for example, we could target all images withing some div marked with an id of “container”:

sir.swap("#container img");

We can even use attribute selectors to specify our target images. For example, we may target all images containing an alt attribute of “Pancakes”:

sir.swap("img[alt='Pancakes']");

The possibilities for targeting images are virtually endless!

And that’s all there is to it! At this point, you should be up and running with swfIR. It may seem like a lot to read through, but once you get everything setup and configured properly, using swfIR is really quite straightforward, even fun! Now, before digging into some specific code examples and recipes, let’s cover a few important notes concerning the implementation and functionality of swfIR.

Important Notes

Custom swf file location

As discussed in step 2 of the “Application” section above, you must explicitly define the location of the swfir.swf file only if it is located in a different directory than the swfir.js file. To do this, add the following line of code to your style parameters:

sir.specify("src", "http://domain.tld/different/path/swfir.swf");

As usual, edit the file path to reflect the actual location of the file on your web server. Here is how the code appears when placed correctly in our working example:

<script type="text/javascript">
	window.onload = function() {
		var sir = new swfir();
		sir.specify("border-width", "25");
		sir.specify("border-color", "fff");
		sir.specify("src", "http://domain.tld/different/path/swfir.swf");
		sir.swap("#example");
	}
</script>

Elasticity settings

When setting the elasticity parameter to “true”, swfIR will resize your image(s) using ems rather than pixels. This functionality enables your styled images to automatically resize along with text and other resizable elements. You may also specify an exact pixel-to-em ratio (such as 10 for a base-font size of 62.5%) to bypass the auto calculation and decrease rendering time.

Targeting all images

To target all images — i.e., all <img> elements — on the page, we would write our example like so:

<script type="text/javascript">
	window.onload = function() {
		var sir = new swfir();
		sir.specify("border-width", "25");
		sir.specify("border-color", "fff");
		sir.specify("src", "http://domain.tld/different/path/swfir.swf");
		sir.swap("img");
	}
</script>

As you can see, we have simply replaced the id value in our swap() method with “img”.

Current issues

Unfortunately, there are several issues that may interfere with flawless swfIR functionality:

  • Resizing/zooming in Opera crashes the browser
  • Flash of unstyled content: images load first before JavaScript replaces them
  • alt text is not preserved upon replacement
  • HTML right-click options are disabled
  • Incompatible with other JavaScript libraries like Prototype or MooTools
  • Doesn’t work with hot-linked images because of security restrictions in Flash

The swfIR team assures us that they are diligently working on solutions for these issues. ;) Now, with that out of the way, lets dive into some tasty little swfIR recipes!

Examples and Recipes

With an understanding of swfIR and how it works, we are now ready to dig into some tasty little code recipes — simply copy, paste, and edit to suit your specific needs! If you have other handy swfIR recipes that you would like to see here, drop a comment and I’ll post it along with a credit link to your site! :)

Rounded Corners

Complete recipe for white, rounded borders applied to all <img> elements. Edit paths and values, delete any extraneous lines, and/or add additional parameters as needed:

<script type="text/javascript" src="http://domain.tld/path/swfir.js"></script>
<script type="text/javascript">
	window.onload = function() {	
		round = new swfir();
		round.specify('src', 'http://domain.tld/path/swfir.swf');
		round.specify('border-color', 'ffffff');
		round.specify('border-radius', '10');
		round.swap("img");
	}
</script>

Rotated Images

Complete recipe for slight image rotation applied to all <img> elements. Edit paths and values, delete any extraneous lines, and/or add additional parameters as needed:

<script type="text/javascript" src="http://domain.tld/path/swfir.js"></script>
<script type="text/javascript">
	window.onload = function() {	
		rotate = new swfir();
		rotate.specify('src', 'http://domain.tld/path/swfir.swf');
		rotate.specify('rotate', '-5');
		rotate.swap("img");
	}
</script>

Elastic Images

Complete recipe for elasticity applied to all <img> elements. Edit paths and values, delete any extraneous lines, and/or add additional parameters as needed:

<script type="text/javascript" src="http://domain.tld/path/swfir.js"></script>
<script type="text/javascript">
	window.onload = function() {
		var elastic = new swfir();
		elastic.specify('src', 'http://domain.tld/path/swfir.swf');
		elastic.specify('elasticity', 'true');
		elastic.swap("img");		
	}
</script>

Multiple Images

Complete recipe for slight image rotation applied to two different <img> elements, identified via right and left, respectively. Edit paths and values, delete any extraneous lines, and/or add additional parameters as needed:

<script type="text/javascript" src="http://domain.tld/path/swfir.js"></script>
<script type="text/javascript">
	window.onload = function() {	
		rotate_01 = new swfir();
		rotate_01.specify('src', 'http://domain.tld/path/swfir.swf');
		rotate_01.specify('rotate', '-5');
		rotate_01.swap("#left");

		rotate_02 = new swfir();
		rotate_02.specify('src', 'http://domain.tld/path/swfir.swf');
		rotate_02.specify('rotate', '5');
		rotate_02.swap("#right");
	}
</script>

Multiple Styles

Complete recipe for multiple styles applied to all images within a div marked with an id of “targeted”. Edit paths and values, delete any extraneous lines, and/or add additional parameters as needed:

<script type="text/javascript" src="http://domain.tld/path/swfir.js"></script>
<script type="text/javascript">
	window.onload = function() {
		sir = new swfir();
		sir.specify("rotate","-5");
		sir.specify("shadow-blur", "15");
		sir.specify("border-width", "20");
		sir.specify("border-radius", "15");
		sir.specify("border-color", "fff");
		sir.specify("background-color", "000");
		sir.specify('src', 'http://domain.tld/path/swfir.swf');
		sir.swap("#targeted img");
	}
</script>

A Specific Implementation..

Here is a specific implementation that I used recently on a client’s site. The trick for this setup involves styling multiple images with multiple styles, and also placing all of the stylistic parameters in an external JavaScript file to keep things 100% unobtrusive and sweet. At this point, all of the style parameters should speak for themselves, so I will forego another elaborate discussion concerning the intrinsic mechanics of this specific application. Note that, in order to get this technique to work, the <script> call to the external swfir.js JavaScript file must be placed in the document <head>; the script will not work when called from the bottom of the <body> element. Here is the code that was included at the bottom of the swfir.js JavaScript file itself:

// set swfir variables
function set_variables() {	
	kel = new swfir();
	kel.specify("rotate","5");
	kel.specify("shadow-blur", "10");
	kel.specify("border-width", "7");
	kel.specify("shadow-angle", "60");
	kel.specify("shadow-offset", "5");
	kel.specify("border-radius", "10");
	kel.specify("border-color", "cccccc");
	kel.specify('src', 'http://domain.tld/javascript/swfir.swf');
	kel.swap("#model");
	hat = new swfir();
	hat.specify("shadow-blur", "10");
	hat.specify("border-width", "5");
	hat.specify("shadow-angle", "60");
	hat.specify("shadow-offset", "5");
	hat.specify("border-radius", "10");
	hat.specify("border-color", "cccccc");
	hat.specify('src', 'http://domain.tld/javascript/swfir.swf');
	hat.swap(".product");
}
// onload event function
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
}
addLoadEvent(set_variables);

Also note that the onload event function can be anything you wish; no need to use this exact method, especially if you have an existing onload event function available elsewhere.

Hit the lights..

In this extensive tutorial, we have covered everything you need to know to successfully deploy swfIR on your own sites. If you have any questions, concerns, or improvements, please share them via them comments below. And, again, if you have any keen swfIR code recipes, drop them in a comment or email me directly (Jeff at this domain) and I will put those up (along with a link to your site) as well. Alright, that’s gonna do it for this mind-boggling article! I think I’ll take a little break.. ;)

Footnotes

  • 1 Note that, although it isn’t recommended on the swfIR site, it is possible to place this code at the bottom of the external swfir.js document, thereby achieving a more “unobtrusive” implementation. This external placement may not work for all configurations, and is known to fail when the call to the JavaScript file is made from the bottom of the <body> element (as recommended for performance optimization). [ ^ ]

Dialogue

8 Responses Jump to comment form

1Peter

November 9, 2008 at 9:34 am

Not to be confused with sIFR : http://www.mikeindustries.com/blog/sifr/

2Jeff Starr

November 9, 2008 at 9:41 am

Correct, swfIR is for styling images, while sIFR is used for replacing text with images. Thanks for the reminder!

3teddY

November 9, 2008 at 11:06 am

Wow this is definitely some awesome stuff. I guess what makes swfIR very appealing is that if you have basic knowledge of CSS, the possibilities of image styling is almost infinite. I love the fact that it allows CSS selectors, which allows us to style images selectively across the page.

It is tragic that it is incompatible with other javascript libraries like MooTools and Prototype - I hope they can fix the incompatibility issue soon. But if I really wan to use it I wouldn’t mind forgoing the javascript libraries for simple websites.

This is a really comprehensive guide you’ve written about swfIR! Excellent stuff over here ;) thanks for sharing!

4Jeff Starr

November 9, 2008 at 5:10 pm

Hi teddY! Great to see you again! Thanks for the feedback on the article — hopefully it will serve the web-design community well. As for the incompatibility, I wonder if the conflict is with swfobject (which is included in the script), or with the swfIR script itself.. seems like a workaround should be possible. Hopefully they are working on it! In any case, thanks for dropping by, and I am glad you enjoyed the article! :)

5KeeKee

November 12, 2008 at 3:09 pm

Absolutely amazing site, love the design.

6Bobby

November 14, 2008 at 11:34 am

And I thought my job was complicated!

7Geld Lening

November 16, 2008 at 9:40 am

Wow, this is really something I’m going to check out tomorrow! The options seem endless! Thanks for the article!

8Jeff Starr

November 16, 2008 at 4:42 pm

My pleasure! Glad you find the article useful! :)

Subscribe to comments on this post


Share your thoughts..

TopRead official comment policy

← Previous post • Next post →

« Better Default Directory Views with HTAccessThree Years and Counting »

Contact Perishable Press

  • Contact Jeff via form

Search Perishable Press

About Perishable Press

Perishable Press is the virtual playground of Jeff Starr — visionary, founder and lead developer of Monzilla Media, a small web and graphic design company in the lush desert oasis of Moses Lake, Washington. Perishable Press features articles and tutorials on many aspects of digital design..

Read more..

Perishable on Twitter

Google tells users to drop support for IE6! @ http://www.tgdaily.com/content/view/40785/140/

Perishable on Tumblr

WordPress Tip for Multiple Themes

Sunday, 4 January 2009, 5:16 pm

If your site makes available multiple themes for users to choose from, remember to include the JavaScript (or any other required code) for any statistical applications that you might be using, such as Mint, Google Analytics, and so forth. I am not sure about the various WordPress statistics plugins, but they may need to be included as well. A good way to check if your stats plugin is tracking data across all themes is to either visit a few pages that you know others aren’t hitting, or else activate each of the alternate themes and check the source code of each one for the required code.

Earlier today, I realized that only several of my most recent themes included the required JavaScript for Mint and Google Analytics. I am now in the process of editing each of the 18 themes available for users at Perishable Press. Haven’t decided on whether or not both statistics apps are needed for all themes, but I will certainly be using at least one of them to keep an eye on everything.

Insane Christmas

Monday, 22 December 2008, 9:47 pm

For as long as I can remember, Christmas has always been a relatively peaceful affair. Sure there’s the usual holiday stress — traffic, shopping, presents, relatives, and all that goes with the preparation of a traditional celebration, but when it’s all said and done, you get to relax and enjoy the peace and harmony of gathering together and basking in the reason for the season: the birth of Christ.

This year, however, the stress factor has been kicked up a few notches, making for a rather insane Christmas if I do say so myself. In addition to the usual holiday chaos, we are currently purchasing a brand new home, and quickly realizing the incredible amount of work involved in the process. If you’ve ever bought a newly built home, you know exactly what I am talking about here.

Plus, as if all the paperwork, inspections, insurance, costs, and anxious anticipation weren’t enough to confound the usual holiday stress, we are also packing up everything, dealing with kids, working full-time jobs, and — beginning on Christmas Eve — moving into our new house.

It certainly is all a great joy and blessing to have such amazing things going on, but combined with the work that I do on the Web — blogging, designing, projects, helping people, and so on — it really becomes all too much rather quickly. We are doing are best to get through everything with our sanity intact, but I have to admit that this is the most insane Christmas I have ever experienced.

New (4G) Blacklist Now in Beta

Monday, 22 December 2008, 9:27 pm

Just a quick note to anyone interested in securing their websites against malicious activity, spam, and other nonsense. Several months after releasing my 3G Blacklist, I have finally begun work on the next incarnation of the blacklist: the 4G Firewall!

The first part of the blacklist is now ready for testing, and I plan on setting it up on Perishable Press within the next few days. While testing on my own site, I thought it would beneficial to also invite a few “beta” testers to run the code on their own site(s) as well.

So, if you have a site that receives its share of malicious attacks, and cracker exploits, drop me a line via the contact form at Perishable Press and I will send you the initial block of HTAccess directives. This version of the Blacklist is looking better than ever, and I look forward to releasing the complete version to the public early in 2009.

Thanks for the Free Traffic and Link Juice

Sunday, 7 December 2008, 1:26 pm

Just wanted to thank the fine folks at fafich.ufmg.br for all the free traffic and link juice. Thanks to their misapplication of my comprehensive canonicalization code, every non-canonical version of their 21,700 indexed pages points directly to my site, Perishable Press. This means that every one of their permalink URLs that is mistyped, lacks the “www” prefix, or contains the superfluous “index.php” file name is directed via permanent redirect directly to the home page of my site.

I have tried contacting the site owner(s) about this situation, but it has been over a week and I have yet to hear anything back. Hopefully, they will take notice soon and correct the issue by properly configuring their htaccess file, but in the meantime, I certainly don’t mind the extra link juice and free traffic! :)

No Plugin Needed for Feed Delay

Monday, 24 November 2008, 10:01 am

I recently saw a WordPress plugin that was designed to delay the publication of your WordPress feed by any specified time interval. While it is a good idea to carefully proofread your content before posting it, a plugin certainly is not required to do so.

As savvy WordPress users already know, WordPress has a built-in post-preview feature that enables authors to view their unpublished content as a published post. This enables authors to do any amount of proofreading and browser checking until they are satisfied with the results.

To do this, simply write your post as usual, and then click on the “Preview this post” button on the right-hand side of the screen. In older versions of WordPress (less than 2.5, I think), you actually need to save (without publishing!) the post first and then re-open it as if to continue editing. You will then see a “Preview »” link sort of hidden (due to poor CSS design) in the upper-right corner near the edit post field. Right-click on that link to open in new tab and you are good to go.

No extra plugin needed! :)

Read more on Tumblr..

Subscribe to Comments Recent Dialogue

  • Mark: There we go! That's the way to do it! Thanks, Jeff!...
  • Jeff Starr: Well said, Mark! Here is some news that I find ...
  • Jeff Starr: Thank you all for the great feedback! I wrote this article as a way to purge some of my thoughts on Twitter, but now see that some of...
  • Jeff Starr: Thank you so much for the thoughtful feedback, Adrian. It has been a good year indeed, and I certainly hope that 2009 brings many ble...
  • Jeff Starr: Hi heywho, glad to hear you are doing well! ;) I wish I could join in the festivities.. it has been so long that I almost have forgot...
  • Rob Barrett: Thanks for posting about the Stealth Publish plugin -- just what I needed for my site. Works perfectly!...
  • Jeff Starr: Hi Chiwan, I got your email and have sent some information that may help you with this. Cheers, Jeff...
  • Chiwan: Hi. This is cool. So I can I replace the clock that comes with your Apathy theme with this clock? If that's not possible, how do ...
  • Brass Engraved: Thankyou very much for this, worked like a dream!...
  • Patrix: I'm using FeedBurner and the Feedsmith plugin for my filter blog, DesiPundit. I found your post via the WordPress page for RSS feeds ...

Read more recent comments..

Attention: Do NOT follow this link!