Sunday, May 9, 2010

Stupid Blog Tricks - Randomized Header Image

I did a little tinkering under the hood, and whenever I do something like this I like to document the process so I can time stamp it for later review (in case I need to redo it), and as an added bonus anyone interested in sprucing up their own blog can follow along at home.

I took my blogroll over to the right (which actually probably needs an update) a step further than just making a list of links, and created little graphics for each site that link to their respective URLs. Each time you load my page, a random one is chosen to be displayed. It breaks up monotony, while still giving "Mad Props, Dawg" to my respected peers. I liked the idea of the random image display, and tweaked the code to replace my header images, too.

Let's Java(SCRIPT!1!)!

The blogroll code is pretty straightforward. Before you get all freaked out, just understand that reading code is actually not that tough, it's writing it that takes the understanding. That said, I didn't write this code from scratch. I took an existing random image displayer and futzed it around to suit my purposes.

There are three basic parts of the code. One that generates a random number, one that takes that number and pulls the associated 'random image', and one that slaps it all together for display.

The first part starts the Javascript, and grabs a number:


<script type="text/javascript">
<!-- Begin

rnd.today=new Date();
rnd.seed=rnd.today.getTime();


It takes the full Date (rnd.today), and converts that to a number (getTime "Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object"), and defines that result as "rnd.seed". This is the basis of our random seed. In this manner, it isn't a random number at all. You could theoretically predict what image will appear next time you hit refresh assuming you can do some math really, really quickly. ;)


function rnd() {
rnd.seed = (rnd.seed*9301+49297) % 233280;
return rnd.seed/(233280.0);
};



It takes that number (our rnd.seed), and multiplies it by some number (9301), adds it to another number (49297), and then deals the remainder ("%" = " The % operator returns the remainder of two numbers. For instance 10 % 3 is 1 because 10 divided by 3 leaves a remainder of 1") in terms of the number 233280, then divides the result by that number again (which would produce a whole number? To be perfectly honest, I'm not sure why these specific numbers were chosen. This is the part of the code that wasn't mine, but I understand the reason it's there. We're basically boiling today's date down to a number, with the understanding that at different points in the day, it will be a different number (duh). Whether 233280, 49297, and 9301 have some specific purposes or not eludes me. Maybe they just rolled their face on the number pad for randomness.


function rand(number) {
var result = Math.ceil(rnd()*number);
if (!result)result++;
return result
};


This is another function ("rand") that increments the number we receive to the next whole number? I don't actually see the math happening behind the scenes, but I imagine we end up with numbers like 4.82767382762, and this pushes it up to be "5", or else maybe we end up with 0 sometimes, and this keeps it clean by pushing that up to a 1. Whatever the point, it's incrementing (the "result++"). The next little chunk just defines a bunch of HTML-y variables... things like where the link points to, the width and height of our images (they can vary, although they don't), and how many images we're dealing with.


var ad_cnt1 = 10;
var ad1 = rand(ad_cnt1);
var link1;
var adBanner1;
var width1
var height1


PHEW. Ground work laid!

Now on to the easier part: Photoshopping and uploading images somewhere.

I made a bunch of little images (200x150, remember, we're still dealing with my Blogroll section here), and threw them up in a specific post that no one ever sees. It's there, but I just gave it an old date so it wouldn't show up on my front page. You can view it here. I just cram images in that post whenever I want to hotlink an image anywhere. I figured it's better than using Imgshack or something, since it's a blogger post, and Google doesn't ever give 'bandwidth expired' errors.

The next section is me just filling in the blanks for each link:


if (ad1==1)
{
link1="http://pinkpigtailinn.blogspot.com";
adBanner1="http://3.bp.blogspot.com/_8UvQIJZJWuI/Sgl5O3p8j0I/AAAAAAAABOw/zufb1KM5mdM/s200/ppi.gif";
width1="200";
height1="150";
alt1="Pink Pigtail Inn";
}
if (ad1==2) {
link1="http://esc-hatch.blogspot.com";
adBanner1="http://1.bp.blogspot.com/_8UvQIJZJWuI/Sgjmad6JrgI/AAAAAAAABNg/MBXjzQYmRzY/s200/hatch.gif";
width1="200";
height1="150";
alt1="Escape Hatch";
}
if (ad1==3) {
link1="http://tobolds.blogspot.com/";
adBanner1="http://4.bp.blogspot.com/_8UvQIJZJWuI/Sgl5SVGTKWI/AAAAAAAABPQ/pj3dBCKoqFI/s200/tobold.gif";
width1="200";
height1="150";
alt1="Tobold";
}


...yadda yadda yadda for ten links....


You can see at the beginning of each section, I say "if (ad1==3)" which is me saying "after all the math, if the number we arrive at is equal to 3, then display the third image/link... which is this image... this link... this height and width... and this alt text".

The last section takes all of that and strings it together as a line of HTML that Blogger can interpret:


document.write('<center><a href="' + link1 + '" target="_blank">');
document.write('<img src="' + adBanner1 + '" width=' + width1 + ' height=' + height1 + ' border=0 alt="' + alt1 + '"></a>');
document.write('</center>');
// End -->
</script>


...it just takes each element and adds ("+") the next chunk. It tells it to center the selected image with no border, and display it!

Whew.

Basically, I'm getting way too into detail here for those that care. If you don't care, you could still easily use this code (with your own uploaded images and links) by only changing the section in the middle. The part that actually lists the link URLs and image URLs. Everything else will just work.

Here's the FULL script, all together:


<script type="text/javascript">
<!-- Begin
rnd.today=new Date();
rnd.seed=rnd.today.getTime();

function rnd() {
rnd.seed = (rnd.seed*9301+49297) % 233280;
return rnd.seed/(233280.0);
};

function rand(number) {
var result = Math.ceil(rnd()*number);
if (!result)result++;
return result
};
var ad_cnt1 = 10;
var ad1 = rand(ad_cnt1);
var link1;
var adBanner1;
var width1
var height1
if (ad1==1)
{
link1="http://pinkpigtailinn.blogspot.com";
adBanner1="http://3.bp.blogspot.com/_8UvQIJZJWuI/Sgl5O3p8j0I/AAAAAAAABOw/zufb1KM5mdM/s200/ppi.gif";
width1="200";
height1="150";
alt1="Pink Pigtail Inn";
}
if (ad1==2) {
link1="http://esc-hatch.blogspot.com";
adBanner1="http://1.bp.blogspot.com/_8UvQIJZJWuI/Sgjmad6JrgI/AAAAAAAABNg/MBXjzQYmRzY/s200/hatch.gif";
width1="200";
height1="150";
alt1="Escape Hatch";
}
if (ad1==3) {
link1="http://tobolds.blogspot.com/";
adBanner1="http://4.bp.blogspot.com/_8UvQIJZJWuI/Sgl5SVGTKWI/AAAAAAAABPQ/pj3dBCKoqFI/s200/tobold.gif";
width1="200";
height1="150";
alt1="Tobold";
}
if (ad1==4) {
link1="http://spinksville.wordpress.com/";
adBanner1="http://3.bp.blogspot.com/_8UvQIJZJWuI/Sgl5PTVGISI/AAAAAAAABPI/IRqRHAWE8zQ/s200/spinks.gif";
width1="200";
height1="150";
alt1="Spinksville";
}
if (ad1==5) {
link1="http://stylishcorpse.wordpress.com/";
adBanner1="http://4.bp.blogspot.com/_8UvQIJZJWuI/Sgl5AfZPzJI/AAAAAAAABOI/hbgBBSSggJU/s200/corpse.gif";
width1="200";
height1="150";
alt1="Stylish Corpse";
}
if (ad1==6) {
link1="http://word-of-shadow.blogspot.com/";
adBanner1="http://3.bp.blogspot.com/_8UvQIJZJWuI/Sgl5PCZzMII/AAAAAAAABPA/UXp-5JHdbOE/s200/shadow.gif";
width1="200";
height1="150";
alt1="Word of Shadow";
}
if (ad1==7) {
link1="http://capnjohnsblog.blogspot.com/";
adBanner1="http://1.bp.blogspot.com/_8UvQIJZJWuI/Sgl5Awzy9eI/AAAAAAAABOg/gZzaPlRounw/s200/john.gif";
width1="200";
height1="150";
alt1="Cap'n John's Blog";
}
if (ad1==8) {
link1="http://rog.gameslate.com/";
adBanner1="http://4.bp.blogspot.com/_8UvQIJZJWuI/Sgl5PHoIeII/AAAAAAAABO4/6UU4X8FnJJU/s200/rog.gif";
width1="200";
height1="150";
alt1="NecroRogIcon";
}
document.write('<center><a href="' + link1 + '" target="_blank">');
document.write('<img src="' + adBanner1 + '" width=' + width1 + ' height=' + height1 + ' border=0 alt="' + alt1 + '"></a>');
document.write('</center>');
// End -->
</script>


Sweet, it's Javascript, where does it go? To add the element itself, you just check your blogger layout, and "add a gadget" to the sidebar, choosing the "HTML/Javascript" choice. Here's a one page tutorial on that, it's simple, I don't need to retype it here.



SO! How is that any different from changing your blog header? Glad you asked! Blogger templates tend to dumb things down for you, because they don't want you breaking your blog (a good thing, in most cases). So if you open your normal layout 'header' section, you don't get an option to paste Javascript in, and you can't Add a Gadget to the top of your blog. Unless we force it.

Open the HTML of your blog template (Customize, Layout, Edit HTML), and Ctrl-F to find the following chunk of code:


<div id='header-wrapper'>
<b:section class='header' id='header' maxwidgets='1' showaddelement='no'>
<b:widget id='HTML4' locked='true' title='' type='HTML'/>
</b:section>
</div>


We're going to edit those three values I've bolded, to:


<div id='header-wrapper'>
<b:section class='header' id='header' maxwidgets='2' showaddelement='yes'>
<b:widget id='HTML4' locked='false' title='' type='HTML'/>
</b:section>
</div>




Save your layout, and now you can Add a Gadget to your header, paste in the relevant code, remove your old header, and WOOOOOOOOOOOOOOOOO

(I know nobody will do this; but I did, dammit, and this is how.)

My final Header Gadget's code:


<script type="text/javascript">
<!-- Begin
rnd.today=new Date();
rnd.seed=rnd.today.getTime();

function rnd() {
rnd.seed = (rnd.seed*9301+49297) % 233280;
return rnd.seed/(233280.0);
};

function rand(number) {
var result = Math.ceil(rnd()*number);
if (!result)result++;
return result
};
var ad_cnt1 = 10;
var ad1 = rand(ad_cnt1);
var link1;
var Header1;
var width1
var height1
if (ad1==1) {
link1="http://ixobelle.com";
Header1="http://2.bp.blogspot.com/_8UvQIJZJWuI/S94zIDwdzAI/AAAAAAAAB3M/ig5sQEjLwMc/s1600/four-toon.png";
width1="733";
height1="163";
}
if (ad1==2) {
link1="http://ixobelle.com";
Header1="http://4.bp.blogspot.com/_8UvQIJZJWuI/S94zB_SwONI/AAAAAAAAB3E/fhoNldMHOLw/s1600/rocketmount.png";
width1="733";
height1="163";
}
if (ad1==3) {
link1="http://ixobelle.com";
Header1="http://4.bp.blogspot.com/_8UvQIJZJWuI/S95Gg-KodwI/AAAAAAAAB3U/oPdHYdpFoNQ/s1600/old-login.png";
width1="733";
height1="163";
}
if (ad1==4) {
link1="http://ixobelle.com";
Header1="http://4.bp.blogspot.com/_8UvQIJZJWuI/S98wCEcaRQI/AAAAAAAAB38/2TcG97vatGg/s1600/sham-buff.jpg";
width1="733";
height1="163";
}
if (ad1==5) {
link1="http://ixobelle.com";
Header1="http://2.bp.blogspot.com/_8UvQIJZJWuI/S98ossgm6jI/AAAAAAAAB3k/LLDzPjZ81N0/s1600/druid-terrokar.png";
width1="733";
height1="163";
}
if (ad1==6) {
link1="http://ixobelle.com";
Header1="http://1.bp.blogspot.com/_8UvQIJZJWuI/S98t4h8RdGI/AAAAAAAAB30/xL0VHNytnUw/s1600/priest-buff.jpg";
width1="733";
height1="163";
}
if (ad1==7) {
link1="http://ixobelle.com";
Header1="http://2.bp.blogspot.com/_8UvQIJZJWuI/S-WoJDAKw2I/AAAAAAAAB4M/fdk5hZ2zd-M/s1600/rollcage.jpg";
width1="733";
height1="163";
}
if (ad1==8) {
link1="http://ixobelle.com";
Header1="http://4.bp.blogspot.com/_8UvQIJZJWuI/S94zB_SwONI/AAAAAAAAB3E/fhoNldMHOLw/s1600/rocketmount.png";
width1="733";
height1="163";
}
if (ad1==9) {
link1="http://ixobelle.com";
Header1="http://2.bp.blogspot.com/_8UvQIJZJWuI/S94zIDwdzAI/AAAAAAAAB3M/ig5sQEjLwMc/s1600/rocketmount.png";
width1="733";
height1="163";
}
if (ad1==10) {
link1="http://ixobelle.com";
Header1="http://4.bp.blogspot.com/_8UvQIJZJWuI/S94zB_SwONI/AAAAAAAAB3E/fhoNldMHOLw/s1600/rocketmount.png";
width1="733";
height1="163";
}
document.write('<center><a href="' + link1 + '" target="_self">');
document.write('<img src="' + Header1 + '" width=' + width1 + ' height=' + height1 + ' border=0 alt="' + '"></a>');
document.write('</center>');
// End -->
</script>


You can see the images I put up in another fake image post here.

I intend to make more (currently the rocketmount.png image is 4 of the 10 choices).

Anyway, this post took way longer than it was supposed to, but now the knowledge is out there on the intertrons for everyone.

Hooray!

7 comments:

HP said...

Wow, nice...

Be nice to know how to do it if I wanted to =)

Not much of a graphic designer though.

I like your headers, very clean.

scraphammer said...

Spiffy! Though it seems a bit complex for something that could be done in PHP with less then a quarter of the code (also server side rather then client side), I'm willing to be that Blogger doesn't make it so easy.

pambuk said...

Java is a different language than Javascript...

Ixobelle said...

Let's JAVASCRIPT!

Reaper said...

I have little experience with JavaScript, but it seems to me you could get rid of the "rnd" function (since all it does is return a number between 0 and 1 in a pretty round about way) and use Math.random() instead.
In addition, in the rand(number) function, checking whether the return value is 0 (!result) is kind of iffy (if you want to check for zero, at least use == 0) and unnecessary, since all it guarantees is that the function never returns 0, but that would only happen if you pass in a negative number as the argument anyways.
If you DO pass in a negative number, the function might return a number smaller than zero, which is probably not what you want either.
I know you didn't write this code, but just in case someone copies it from here you might consider cleaning it up so no one runs into unexpected problems.

We Fly Spitfires said...

Just curious, but was there a reason you didn't use the JavaScript math.random() function?

Love your headers btw! :)

Ixobelle said...

Hmm..

yeah, as I said, I didn't write it from scratch so much as twist it to serve my own (nefarious?) purposes. I had assumed the first section was what was needed to grab the number, since that's how the original example had it set up.

Looking here: http://www.shawnolson.net/a/789/make-javascript-mathrandom-useful.html

I can see it wouldn't be that hard to alter and make cleaner. Might jump on that when the kid naps today.