So in Part 1 and Part 2 we created the CSS3 animation behind the flipping countdown clock based off this example from CodePen. Now we’re going to tweak the CodePen example in order to countdown to a specific date. Here’s what our finished product will be after styling.
We’re going to handle our clock a little differently than the CodePen example. For example, we’ll be counting down, not up. We’ll also need a way to set our time when the page first loads. We’ll do this by getting the milliseconds difference between the time when the page loads and the time to which we’re counting down. Instead of having HTML for each of our digits 1-9 we’re going to set the current digit and the upcoming digit through JS.
We’re going to focus on the JS behind the project in this one so go back to last two parts if you don’t have a good grasp of what’s going on with the HTML and CSS. That being said the HTML we’ll be using for this section is slightly different (i.e. named better) than the previous parts, and also lifted almost directly form CodePen. We’re starting with 0 and 1, but our JS is going to replace those with the proper numbers when the page loads.
<ul class="flip secondPlay"> <li> <a href="#"> <div class="up"> <div class="shadow"></div> <div class="inn">0</div> </div> <div class="down"> <div class="shadow"></div> <div class="inn">0</div> </div> </a> </li> <li> <a href="#"> <div class="up"> <div class="shadow"></div> <div class="inn">1</div> </div> <div class="down"> <div class="shadow"></div> <div class="inn">1</div> </div> </a> </li> </ul>
Ok, so we’ve got the HTML set up. I’m not going to copy all of the CSS into you can check out the file here. (Note: Since we’re using HTML 5 Boilerplate our styles don’t start until the “Author’s Custom Styles” section).
Let’s get into the JS. First thing we’ll need to do is set up our date. We’ll start by creating a getDate function.
function getDate() { currentTime = new Date(); countdownTime = Date.parse("April 1, 2013 21:10:00"); countdownTotal = countdownTime - currentTime; }
Alright, first thing we do in our getDate function is getting the date by setting a variable called currentTime equal to a new date object. Next, we set our countdownTime by parsing a date out of a string date we choose (in our example April 1, 9:10 PM central time). These give us the number of milliseconds from January 1, 1970 to our currentTime and to our countdownTime respectively. We then take the difference of these two numbers and set it as our countdownTotal which gives us the number of milliseconds between the current time and the time to which we’re counting down. That’s cool and all, but that just gives us a number with like 20 digits (Note: I did not actually count).
So the next thing we need to do is make this number a little more usable by calculating how many days, hours, minutes and seconds our countdownTotal represents.
function getDate() { currentTime = new Date(); countdownTime = Date.parse("April 1, 2013 21:10:00"); countdownTotal = countdownTime - currentTime; // Set days, hours, mins, secs through the power of math days = Math.floor( countdownTotal / (1000*60*60*24) ); hours = Math.floor( countdownTotal / (1000*60*60) ); mins = Math.floor( countdownTotal / (1000*60) ); secs = Math.floor( countdownTotal / 1000 ); }
So we’ve created variables to hold our days, hours, minutes and seconds. We then set these by dividing countdownTotal by the number of milliseconds in the unit of time we’re measuring. So for days we take the Math.floor of countdownTotal / (1000*60*60*24). So that’s 1000 milliseconds in a second * 60 seconds in a minute * 60 minutes in an hour * 24 hours in a day. So when we run that we know exactly how many days we have in our countdownTotal. Repeat for hours, minutes, and seconds as shown above. You’ll notice hours dropped *24. Obviously when you’re trying to calculate hours you don’t need to know how many hours are in a day so you stop at *60 minutes in an hour.
That’s a bit more usable, but we still only know the total number of days, hours, mins and secs in our countdownTotal. So say if days = 10 then hours will equal 240. That doesn’t really help us because we want to know how many hours are left after we take the days out of our total.
function getDate() { currentTime = new Date(); countdownTime = Date.parse("April 1, 2013 21:10:00"); countdownTotal = countdownTime - currentTime; // Set days, hours, mins, secs through the power of math days = Math.floor( countdownTotal / (1000*60*60*24) ); hours = Math.floor( countdownTotal / (1000*60*60) ); mins = Math.floor( countdownTotal / (1000*60) ); secs = Math.floor( countdownTotal / 1000 ); // Determine the number of days first. Hours = total time minus days. Etc dd = days; hh = hours - days * 24; mm = mins - hours * 60; ss = secs - mins * 60; }
So our first step is to determine how many days we have so we set our new variable dd = days. Notice we used Math.floor when calculating days so say there’s 10 days and 12 hours left or 10.5 days it drops the .5 so we have only how many full days are left. Our hours will handle the other 12 hours. So now that we have our dd set to days we need to find out how many hours are left in our countdown. So we take hours – days * 24. So if we use our 10.5 day total our countdownTotal variable would be at 907,200,000 milliseconds. Days would then be floor of 907,200,000 / 86,400,000 or 10 (10.5 rounded down). Hours would then be the floor of 907,200,000 / 3,600,000 or 252 (10.5 days x 24 hours = 252 hours). So to set our hours we would set hh = 252 – (10 * 24) or 252 – 240 which equals 12 giving us our 12 leftover hours. So now dd = 10 and hh = 12. So we have 10 days and 12 hours or 10.5 days. In this example we don’t have leftover minutes and seconds, but they’re handled the same way. mm = mins – (hours * 60) and ss = secs – (mins * 60).
Alright, the last thing we’re going to do in our getDate function is pull out the individual digits from dd, hh, mm, ss variables. So if we have 32 seconds left we need to pull out “3” and “2” so we can put them in our HTML.
function getDate() { currentTime = new Date(); countdownTime = Date.parse("April 1, 2013 21:10:00"); countdownTotal = countdownTime - currentTime; // Set days, hours, mins, secs through the power of math days = Math.floor( countdownTotal / (1000*60*60*24) ); hours = Math.floor( countdownTotal / (1000*60*60) ); mins = Math.floor( countdownTotal / (1000*60) ); secs = Math.floor( countdownTotal / 1000 ); // Determine the number of days first. Hours = total time minus days. Etc dd = days; hh = hours - days * 24; mm = mins - hours * 60; ss = secs - mins * 60; // Set time. Going right to left for some reason. My bad. firstDigit = Math.floor(ss % 10); secondDigit = Math.floor(ss / 10); mmFirstDigit = Math.floor(mm % 10); mmSecondDigit = Math.floor(mm / 10); hhFirstDigit = Math.floor(hh % 10); hhSecondDigit = Math.floor(hh / 10); ddFirstDigit = Math.floor(dd % 10); ddSecondDigit = Math.floor(dd / 10); }
Alright I started with the far right digit for this which may be a little confusing. So if we have 32 seconds I’m setting the “2” first. So I created a variable firstDigit to store this “2”. How we’re doing this is we’re taking ss (in this example 32) is taking ss % 10 which gives us the remainder when ss is divided by 10 so 32 % 10 equals 2 (3 with a remainder of 2). Boom, there’s the 2 we need. So to set our secondDigit we take 32 / 10 = 3.2 and take the Math.floor of that so we round down to 3. There’s our 3. We’ll insert these into our HTML soon.