After a bit of banter in the office about favicons (always a nice little extra touch) we noticed that firefox can support animated ones too. Never one to not take it a step further, I thought – why not use that tiny little 16 pixel square to convey even more – hence the frivolity of the code below (and what you should see if viewing this in firefox – a tiny ticker in the favicon space to the left of the address bar or tab, in this case getting Aberdeen’s current weather info from a BBC weather rss feed)
<pre>
//
// requires a directory called ‘frames’ with write permissions
// and (in wordpress) the theme header.php needs the following line
//
// <link href="favicon.gif" type="image/gif" rel="icon" />
//
// you’ll also need some .htaccess lines to redirect requests for the favicon to this php script
// RewriteEngine on
// RewriteRule favicon.gif favicon.php
//check age and status of previous favicon file
$cachetime = 60*60*4; //4 hours
$iconfile = “favicon.gif”;
if(!file_exists($iconfile) || (time()-filemtime($iconfile)>$cachetime) || filesize($iconfile)==0)
{
//———if file is older than updated interval, or does not exist ————-
// rss reading via simplexml is php 5+ only, else you’d have to use a different method of acquiring rss data
$xml = simplexml_load_file(“http://feeds.bbc.co.uk/weather/feeds/rss/5day/id/1000.xml”);
$content = “”;
$count=0;
foreach($xml->xpath(‘//item’) as $child)
{
$content.=$child->title;
$count++;
// only going to take 1 item from the feed though could iterate through more
// but makes for a lot of frames to generate
if($count==1) break;
$content.=” – “;
}
// find and replace xml degree characters because the pixelfont doesn’t have them
$search = chr(194).chr(176);
$content = str_replace($search,“”,$content);
$font=“04B_03__.TTF”; //a very small pixel font
//fontsize is adjusted as gd2 uses points not pixels
//without this adjustment pixelfonts won’t be as crisp as they should
$fontsize = 8/96*72;
// calculate length of all text
$tb = imagettfbbox($fontsize,0,$font,$content);
$width = 32+$tb[2]-$tb[0];
// create full length image
$im = imagecreatetruecolor($width,16);
$white = imagecolorallocate($im,255,255,255);
//note that the negative color index below turns off anti-aliasing
imagettftext($im,$fontsize,0,16,14,-$white,$font,$content);
imagepng($im,“text.png”);
// calculate how many frames, divide by 2 if you want a smaller gif with less frames. You may want to adjust the convert -delay parameter too
$frames = $width/2;
// loop through frames
$c = 0;
$ppf = 2; //pixels per frame
while($c<$frames)
{
$im_f = imagecreatetruecolor(16,16);
//copy text bit
imagecopy($im_f,$im,0,0,$c*$ppf,0,16,16);
//static top bit
//if($c%2){//blink every second frame for additional irritation
$red = imagecolorallocate($im_f,255,0,0);
imagettftext($im_f,$fontsize,0,3,7,-$red,$font,“M.D”);
//}
$c++;
// create frame number padded with zeros
$cs = sprintf(“%04d”, $c);
//save
imagepng($im_f,“frames/frame”.$cs.“.png”);
imagedestroy($im_f);
}
imagedestroy($im);
// put all those frames into animated gif through the magic of imagemagick
exec(“/usr/bin/convert -delay 20 -size 16×16 -loop 0 -layers Optimize -colors 4 frames/frame*.png favicon.gif”);
// delete all our generated frames else next time we generate we may include spurious frames
//*** CAREFUL WITH YOUR PATH HERE!!! ***
foreach (glob(“frames/*.png”) as $filename) {
unlink($filename);
}
// read the file back out to browser
header(‘Content-Type: image/x-icon’);
readfile($iconfile);
// copy the file across to a .ico file for internet explorer users. they won’t see animation. aww
copy(“favicon.gif”,“favicon.ico”);
}
else
//——— cache is still young so read and output ———–
{
header(‘Content-Type: image/x-icon’);
readfile($iconfile);
}
?>
</pre>
[...] One of our developers has played with this, and created something a bit more advanced! Mike’s blog [ Mike Duguid ] Blog Archive Dynamic animated favicons [...]