CSS 3 Animation? Yes Please!
Ok, I'm so mega busy right now working on Flurl. I need to have it done TONIGHT because I've got other pressing obligations coming up and I just won't have any time to work on it after today.
I wanted to have movement and sound and I wanted it REALLY CORNY as an homage to the flickr pandas from whom it gets it's photos.
Here's a little preview (Webkit only).
That's just a little taste. It's going to be much more. It's going to have music and it's going to have a photo stream.
Just a little tid-bit though I wanted to explain how I animated it (It's a grand total of 62 lines from <html> to </html>). I didn't use any JavaScript at all, it's all CSS3 (amazing!).
First I designed the animation:
@-webkit-keyframes turnit{
from{
-webkit-transform: rotate(0deg);
}
to{
-webkit-transform: rotate(-364deg);
}
}
Yeah, really simple I know. I'm just telling it to rotate from 0deg to -364deg. Note that I named the animation "turnit".
Next I applied the animation to my div.
#turningBG{
-webkit-animation-name: turnit;
-webkit-animation-iteration-count: infinite;
-webkit-animation-duration: 30s;
-webkit-animation-timing-function: linear;
}
Line 1: use the animation "turnit" we defined before. NOTE THAT THE ANIMATION DEFINITION MUST COME BEFORE WE TRY AND APPLY IT. If I tried to use it before I defined it in my stylesheet, nothing would happen.
Line 2: Loop forever.
Line 3: Last for 30s.
Line 4: Make it smooth (linear). Could ease-in or out or whatever, but I wanted it to be seamless with no apparent start or stop.
Notes: If you look at the source you will see that I made my turning div 3200px wide and tall and then put it inside of a container that was 100% wide and tall and overflow hidden to keep there from being scrollbars. I then positioned the div so the center of it would be right under the unicorn's foot.
Here's some reference for css3 animation stuff. Here's some more.
Here's the entire "view source":
Flurl – Part 1.a: Rolling your own JavaScript library, setting up the core
Flurl is a mashup I did recently as a practice exercise.
It takes a flickr panda photo-stream, displays a photo, and uses qurl to make a shortened URL link to the photo.
These are the notes I took while I was doing it.
The project can be found on GitHub at http://github.com/cmcculloh/Flurl
For this exercise I didn't want to use any JavaScript library. Normally I'd use jQuery (naturally) but I wanted to feel the pain of plain jane JavaScript again since it had been well over a year since I had done any AJAX without a library.
I decided I'd roll my own library that I could use to encapsulate the AJAX and DOM selection framework to keep it seperate from the actual app and to simplify my life in actually writing the app.
Since I wanted my library to feel a little jQuerish I decided as an homage I'd name it cQuery and use the _ instead of the $.
Step 1, the ubiquitous self executing anonymous function:
(function(window, document, undefined){})(this, document);
I'll break it down. The starting paren "(" and it's mate are just a "cool guy" coding convention to let people know, "this is weird! This is a library! This ain't yo mama's JavaScript!". It's the same as this:
function(window, document, undefined){}(this, document);
Which is simply just a function that immediately calls itself. The main reason to do this is to prepare our code for minification. When we minify, it will end up something like this:
(function(A,B,C){})(this, document);
So anywhere in our library where we had "window" or "document" or "undefined" it will not be the much shorter "A", "B" or "C", much smaller!
Paul Irish explains this in a *little* more detail in his 10 Things I Learned From the jQuery Source video.
Next we build the core function of our library, add it to the namespace and give it it's "_" shortcut:
var cQuery = function(elm){
};
window.cQuery = window._ = cQuery;
Note that if we didn't do that last line 'cQuery' would not be available in the rest of our JavaScript since it is hidden away inside of the closure we talked about above.
I really like the way jQuery works, and I want my library to mimic this. So calling:
cQuery("#domElementById").someMethod().anotherMethod();
ought to work.
Functions in JavaScript are just Objects that you can invoke. Functions can have their own methods, properties, etc. So basically cQuery is just an object that can DO something on it's own so we can say cQuery() instead of cQuery.doThing(). Much more convenient. So basically our var cQuery = function(elm){} code is just setting up my cQuery library object in a way that it can be called and passed the dom element we are working with.
Since I want to be able to "chain" things in my library, I'll need to add the methods in there that enable my chaining. I do this by ending my cQuery function with a return statement that returns an object containing the methods I wish to be available for chaining, each of these methods in turn returning an instance of the cQuery object (unless the method is specifically supposed to return something else, which makes it a destructive method because it ends my chaining), like in this example:
(function(){
var c = function(){
return{
blah:function(){
alert("blah");
return c();
},
blah2:function(){
alert("blah2");
return c();
}
};
};
window.c = c;
})();
c().blah().blah2();
That's it! Now I've got the core of my JavaScript library all set up, chaining enabled, library closed in but available on the namespace, all ready to be made useful! Here's the code we've got so far:
(function(window, document, undefined) {
var cQuery = function(elm){
//DOM selection and storage will go here
return {
//chain-able library methods go here
};
};
//make sure our library is exposed to the global namespace and make a shortcut "_" so we don't have to type cQuery every time.
window.cQuery = window._ = cQuery;
})(this, document);
Using jQuery to bind a function to a select box change and retrieve the selected value

If you need to bind a function to be called when a user selects an option from a select box using jQuery, you've come to the right place.
There are several different ways to skin this cat, but basically here is what we are going to do:
1. Bind a change event listener to the select box itself
2. When the box is changed, call a function that detects and retrieves the selected value
Here's the code:
$("#selectBoxId").change(function(){
var selectedValue = $(this).find(":selected").val();
console.log("the value you selected: " + selectedValue);
});
Let's break it down line by line.
Line 1:
$("#selectBoxId").change(function(){
$("#selectBoxId") grabs the DOM element out of the html and makes a jQuery object.
.change(function(){}); binds a function to the change event of the select box. Any time anyone changes the selection in the select box this function will fire off
Line 2:
var selectedValue = $(this).find(":selected").val();
var selectedValue creates a new variable that the selected value will be stored in.
$(this) creates a jQuery object based on the select box that triggered the function.
.find(":selected") looks a the select box that triggered the function and finds the option that got selected.
.val() gets the "value" of the selected option.
Line 3:
console.log("the value you selected: " + selectedValue);
this just calls the firebug console in firefox and tells it you want to print something out to it. You don't need this line, but this line shows you that the above code did indeed grab the selected value out of the select box.
Line 4:
});
This just closes the open change function started on line 1.
This code assumes that you have an HTML select box with an id of "selectBoxId". If you have a series of select boxes that all need the same function bound to them for some reason you can give them all the same class name (say "selectBoxesClass") and select them like so: $(".selectBoxesClass").
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Conforming XHTML 1.0 Strict Template</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript">
$(function(){
$("#selectBoxId").change(function(){
var selectedValue = $(this).find(":selected").val();
console.log("the value you selected: " + selectedValue);
});
});
</script>
</head>
<body>
<select id="selectBoxId">
<option>Foo</option>
<option>Bar</option>
<option selected="selected">Beh</option>
</select>
</body>
</html>
Here are some resources for further reading:
jQuery
jQuery change
jQuery find
jQuery val
jQuery :selected selector
jQuery Element selector
jQuery id selector
jQuery class selector
Firefox
Firebug
Firebug Console
My own little dailyWTF
Note: WTF can stand for "Worse Than Failure"...
Yesterday I was re-living my saga on thedailywtf.com. I'm Jared L.
Well, immediately after reading all of that I went and made a big 'ole wtf all on my own. Read on...
Every Wednesday and Friday finishline.com gets updated with new promotional material. Most notable of all of these is the "A1 rotator". This is the flash rotator prominently displayed on the homepage of the website. Each Tuesday and Thursday Sean in marketing will send me (up to) four new .swf files and one .xml file to drop in to the root directory of the site and the A1 rotator will magically update with these new files. I've been doing this bi-weekly for a year and a half and have never personally screwed it up. It's not hard. I copy the files from one directory into another and zip them up and send them over to the build and release manager, Brandon, who sends them over to Verizon who pushes them out to 71 different instances of our website. It functions like clockwork. Until it doesn't. This is a story about a massive multi-layered failure of the A1 rotator and it's 100% my fault.
Thursday afternoon at around 4:30 I received the files from marketing and copied them over into the required directory on my local box. As always, I manually uploaded the files to the QA server (a mirror of production) so marketing could test them. I zipped up the files and e-mailed them Brandon. I didn't bother to go out to our QA server and test them myself because, "hey, I've been doing this a year and a half and have never screwed this step up and I'm really busy and what could possibly be wrong? I just copied some files over, what could I have screwed up?" Oh the fallacy...
At this point, the piece of dung sorry excuse for an e-mail client "Outlook" crashed. I had already sent off the files so I didn't notice.
An hour later when I'm preparing to go home for the day I go to send and e-mail and see that once again Outlook has crashed. I pop it back open and find that I have an e-mail waiting for me from marketing. Five minutes after I sent the zipped files over to Brandon, marketing e-mailed me to let me know that something was wrong with the A1 spot on the QA server. Crap.
I open up Firefox and hit the QA server only to find myself staring at a big empty white space where the A1 rotator should be. WHAT???
Ok, maybe the xml file is pointing at a non-existant swf file and the whole thing is bombing out... What are the names of the files? Oh, there's a complicated one, "a1_jordan_02102010.swf" maybe the xml has that name screwed up. Let's simplify things. I rename the file "a1_jordan.swf" and edit the XML "a1_jordan.swf". Upload. Check. NOPE!
OK, marketing has obviously screwed this all up. Everyone from marketing has gone home at this point so I send an e-mail off requesting corrected files from marketing and prepare to call it a day. But I can't just leave it at that because that would be irresponsible.
I quickly scan the root directory looking to make sure all the swf files are there. Yes. Is the XML file there? Yes. Ok, so banner_rotator.swf should be pulling them in but it's crash... OOOOH NOOOOOO (said in a Tim "the Tool Man" Taylor voice). Suddenly I'm flashing back to the previous Thursday when I'm performing this exact same task. I recall that at that time I was feeling a little "cleany" and I decided that I should go through and remove all the old swf files from promos-gone-by. Sean happened to walk into my cube at exactly that moment and together we review the fifty or so swf files that don't need to be there anymore. Clicking them one by one was going to take too long, so I selected ALL of the swf files and then we went through and de-selected the four required for the next day's A1 rotator. Once I was sure I wasn't going to delete the rotator files, I went ahead and deleted the rest of the swf files. Including the banner_rotator.swf master file that pulls in the xml and the four content swfs. SHOOT!
So I recover the banner_rotator.swf, add it to the root, and send it all back over to Brandon. I follow up with an e-mail absolving marketing and I call it a day. Everything's fine and I even let my boss know what happened assuring him that everything is taken care of. Little do I know...
The next morning as I'm preparing to leave for work I happen to check my work e-mail. The A1 rotator is missing from the site. Apparently the promo push still hasn't run, and the CDN we use has dropped the banner_rotator.swf file since it no longer exists in our build (because I deleted it last Thursday so it was dropped out of the following Thursday's production deploy, which was yesterday). Great. The promo push is about to start though and then everything will be ok. I call a few people and send some e-mails to let everyone know what's going on and leave for work.
When I get into the office I pull up the website and check only to discover that the first spot in the rotation is completely blank. I have several e-mails informing me of this as well. Flash back time... Remember when I renamed the jordan file as part of my debug process? Yeah, me too. Apparently I never put the name back correct but the xml did get switched back. So now I really am missing a swf. I guess the only thing that happens if a swf is missing is that the spot for it in the rotation is just blank. Good thing the only spot that's blank is the very first spot, which is only seen by 100% of our visitors and only clicked on more than anything else in the entire site!
I call Brandon and sheepishly request that he manually go through all 71 instances of our site and rename the file in every one so that we don't have to do an emergency push and incur a fine. Which he does and the whole thing is fixed.
At this point I get up and start looking for my coffee mug. It's missing. I finally stumble across it right next to the coffee machine. Curiously it has a little pile of cream and sugar in it all ready for a cup of jo. It is then that I realize what the root of the whole problem was. I never had my coffee the day before. Why? Because someone took the last of the coffee and didn't start a new pot brewing; when I went to get my coffee the pot was empty. I had started a new pot brewing, got my mug ready, walked away and never came back; resulting in me doing the entire promo push without any caffeine in me. Apparently I just suck without caffeine. And that boys and girls is why you should always start a new pot if you drink the last of the current one. That is also my lame attempt to shift the blame away from myself, lol. No, this was 100% my fault...
JavaScript Arrays – new Array() vs array literal

Do not every say new Array() when creating a new JavaScript Array(). There are differences between creating an array in Javascript using the array literal, or the fully qualified "object" name (Array() vs []), and the bottom line is that the "right" way to do it is "[]" (array literal) instead of "new Array()". Here is why:
- Most experienced JS programmers use []. [] is the way Douglas Crockford teaches it in JavaScript the Good Parts
(they even talk about it in JavaScript: The Definitive Guide
). Also, if you look in the unminified source for the jQuery library, you will never see Array().
- They appear to be nearly identical, except they aren't.
- [] is more terse and readable, especially for nested arrays:
vs:
- Using the Array() keyword makes you think about arrays as being somehow different from plain vanilla JavaScript Objects (which, yes they are in-so-much as they are Objects with extra methods already defined for you). The literal helps you think about them more object-like because [] looks like {}. Plus, [] is more consistent with the way that you then access the array something[0] so there is less to remember.
- Most importantly, Array() doesn't behave uniformly across argument numbers and types. ((new Array(X)).length === 1 for any X as long as typeof(X) != "number" else Array(X).length === X)
TOTW: Google Closure JavaScript Compiler Web Interface
This week's Tool of the Week is Google Closure JavaScript Compiler. I know everyone has probably heard of it, but if you haven't gotten around to checking it out, this post is great for you.
What it does:
Allows you to compile JavaScript down to a compressed form. It reads in your JavaScript, parses it, and re-writes it to be much smaller. This is good for you because it will make your site load faster, much faster in some cases.
When you need it:
- To compress your JavaScript
- To combine multiple JavaScript Files
How to use it:
The Example:
Additional Notes:
Notice in the compile directions there is an @output_file_name parameter. You can change this to something other than "default.js" (you can name it anything you want. Then you can actually access the results by clicking on the link on the right hand pane that says "The code may also be accessed at default.js" (if you rename it it will put the name you put instead of default.js). Here's the file generated by my example.
JavaScript, pass by value & pass by reference
In JavaScript Objects are passed by reference. Primitives are passed by value. I did not know this. I should have, but I didn't. I didn't because I had never done anything destructive on an object before today. Let me elaborate:
Outputs:
3
4
Ouputs:
b 4
b 4
Which means if you do this:
This is the result:
something [Object y=2, Object z=fred, Object a=9, 2 more... 0=Object 1=Object 2=Object 3=Object 4=Object]
something [Object y=2, Object z=fred, Object a=9, 2 more... 0=Object 1=Object 2=Object 3=Object 4=Object]
For those of you slightly newer to JavaScript than me, shift() removes and returns the first element in an array. So, in our "something" array in our object, "x" is stripped out, not only in the copyData object, but also in the data object. This is because both copyData and data are simply REFERENCES to an anonymous object containing an array called "something". Crazy.
Today I was trying to make a copy of an object, and then call shift() on an array inside of the copy. I was baffled when the original object was being affected.
There is no good way to make a true copy/clone of an object in JavaScript. John Resig has a jQuery solution that can be found here: http://stackoverflow.com/questions/122102/what-is-the-most-efficent-way-to-clone-a-javascript-object
Finding the number of hex tiles inside of a hex shaped grid…
EDIT: There is a mathematical formula that is much better than the method I illustrate below. It is: 3n^2 - 3n + 1
A huge thanks to Sam Hughes for very patiently helping me out with this formula. He's the best mathematician I know...
Here's the JavaScript code to execute this formula (just change maxTiles to be however wide your hex grid is):
var maxTiles = 7; var n = Math.ceil((maxTiles - 2) / 2); var numberTiles = 3 * Math.pow(n, 2) - 3 * n + 1;
Below is the original post:
This is kind of like finding the area of a hex grid, except that for some reason none of the formulas I found for doing that would work. Also, finding the area of a triangle made of hex grids won't work with the normal triangle area formula either.
What I am illustrating here is how to find out how many hex tiles are inside of a hex shaped grid of hex tiles.
Here is a picture of the grid:

What you have to do is:
1. Take the half the width of the hex grid rounded down. So, if the hex grid is 7 wide, you take half of seven, 3.5, and round it down to 3. This can also be called "flooring" the number.
2. Take that number and use it to seed a floor loop, which counts down from that number, adding the new number to a grand total each time.
3. Multiply that grand total by 7 and add one for the middle tile (which never got counted).
Here is the code:
var triangleTotal = 0;
for(var spaces = Math.ceil((maxTiles-1)/2); spaces > 0; spaces--){
triangleTotal += spaces;
}
var triangles = triangleTotal * 6;
var numberTiles = triangles + 1;
return numberTiles;
You'll notice that I took the total minus 1 divided by 2 and "ceil"ed it, instead of taking the total divided by two and "floor"ing it. It doesn't matter which you do...
Here's a visualization proving this out:
I only took one math class in college, otherwise this would have probably been very obvious to me as it may seem to you. There is probably even a really fancy easy little formula for this, but I don't know it and couldn't find it...
Here's a page where you can test this formula out in action. Note that a hex is always going to be an odd number of hexes wide, so if you enter an even number and get a funny shaped hex, this formula isn't going to work...
JavaScript Haxagon Game Board with Hexagon tiles
I'm working on a JavaScript version of The Settlers of Catan. The first problem I decided to tackle was constructing (visually and array-structure wise) the game board using nothing but loops (didn't want to hard code it).
This ended up being much more difficult than I thought it would be.
I am going to split this up into two parts:
1. Setting up the game board visually
2. Setting up the array structure
Creating a Hexagonal game board with hexagonal spaces in JavaScript with for loops:
For this to work properly, you must have an even number of columns and rows. I chose seven since that is what makes up the Settlers of Catan game-board.
You have to split the building of the board into three stages:
1. The expanding stage
2. The apex or middle of the board
3. The contracting stage
I placed everything in one large for loop that counted off the "rows".
I figured out that while the rows are less than half the max rows divided by two (and rounded down) the board would be contracting. The number of tiles you would start with would be equal to the maximum number of tiles divided by two, rounded up, plus the current row number.
Once the number of rows equals exactly half the number of maximum tiles (rounded down) you are on the middle row. In this case the number of tiles is the max number of tiles, no math required.
Otherwise, you are in the contracting stage and the number of tiles you need is equal to the maximum number of tiles, minus the current row, minus half of the maximum rounded down.
Sound complicated? That's because it is. This took me about 30 minutes to get straight in my head after studying the game-board shape, tiles, and making several diagrams and sudo-coding and then writing the actual code and fixing bugs (and deciding if I had to round up or down at certain places).
Here is the actual code:
<html>
<head>
<style>
img{
margin-top: -18px;
}
#board{
padding: 50px 25px;
background-color: #000;
}
</style>
</head>
<body>
<div id="board">error loading</div>
</body>
<script>
function boardSetup(){
var max = 7;
var html = "";
for(var row = 0; row < max; row++){
if(row < Math.floor(max/2)){
//place spacer tiles
for(var space = 0; space < (Math.floor(max/2) - row); space++){
html += '<img src="spacerTile.png" />';
}
//place game tiles
for(var cols = 0; cols < (Math.ceil(max/2) + row); cols++){
html += '<img src="tile.png" />';
}
html += "<br />";
}else if(row == Math.floor(max/2)){
for(var cols = 0; cols < max; cols++){
html += '<img src="tile.png" />';
}
html += "<br />";
}else{
for(var space = 0; space < (row - Math.floor(max/2)); space++){
html += '<img src="spacerTile.png" />';
}
for(var cols = 0; cols < (max - (row - Math.floor(max/2))); cols++){
html += '<img src="tile.png" />';
}
html += "<br />";
}
}
document.getElementById("board").innerHTML = html;
}
boardSetup();
</script>
</html>
Here are the images that go with it:
Here is the tile:
Here is the spacer. This one is completely invisible: start->
<-end



















