soum soum - 5 months ago 16
jQuery Question

image based count down clock

I have a count down clock which works absolutely fine. Now the question is can I display images as digits instead of html. I cant seem to figure out the logic how would I approach it. I really dont want to use a plugin for this so that is really not an option.

and the JS for the clock is this

setInterval(function(){
var future = new Date("Jan 20 2014 21:15:00 GMT+0200");
var now = new Date();
var difference = Math.floor((future.getTime() - now.getTime()) / 1000);

var seconds = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);

var minutes = fixIntegers(difference % 60);
difference = Math.floor(difference / 60);

var hours = fixIntegers(difference % 24);
difference = Math.floor(difference / 24);

var days = difference;

$(".seconds").text(seconds + "s");
$(".minutes").text(minutes + "m");
$(".hours").text(hours + "h");
$(".days").text(days + "d");
}, 1000);

function fixIntegers(integer)
{
if (integer < 0)
integer = 0;
if (integer < 10)
return "0" + integer;
return "" + integer;
}


I have stored the images in an array which is this

var linkCons = 'http://soumghosh.com/otherProjects/Numbers/'

var num = [];
var linkCons = "http://soumghosh.com/otherProjects/Numbers/";
for(var i = 0; i < 10; i++) {
num.push(linkCons + "nw" + i + ".png");
}


Thanks to stack overflow folks helping me cleaning the array. Really appriciate it

And here is the working fiddle
http://jsfiddle.net/sghoush1/wvbPq/3/

Answer

You can do it using only one sprite image and this bit of code I created:

LIVE DEMO

enter image description here

jQuery( function($) {

    var fut = new Date("Jan 20 2014 21:15:00 GMT+0200").getTime(),
        obj = {};

    // Number splitter
    function intSpl( i ){
      i = Math.floor(i);
      return [~~(i/10), i%10]; // 37=[3,7] // 5=[0,5] // 0=[0,0] 
    }

    function drawTime(){  
      var now = new Date().getTime(),   
          dif = now<fut ? Math.floor( (fut-now)/1000) : 0;
      obj.s = intSpl(dif % 60);
      obj.m = intSpl(dif/60 % 60);
      obj.h = intSpl(dif/60/60 % 24);
      obj.d = intSpl(dif/60/60/24);  

      for(var key in obj){    
         if(obj.hasOwnProperty(key)){
            for(var i=0; i<2; i++){ // get el ID number (0,1)
                $('#'+ key+i).css({backgroundPosition: -obj[key][i]*50 });
            }
         }    
      }  
    }
    drawTime(); 
    setInterval(drawTime, 1000);

});

This simple HTML:

<div id="clock">   
  <span id="d0"></span>  
  <span id="d1"></span>  

  <span id="h0"></span>  
  <span id="h1"></span>

  <span id="m0"></span>  
  <span id="m1"></span>

  <span id="s0"></span>  
  <span id="s1"></span>  
</div>

and CSS:

#clock span{
  display:inline-block;
  width:50px;
  height:85px;
  background:url('http://i.imgur.com/uBTxTTD.jpg');
  background-position:0 0;
}
#clock span:nth-child(even){
  margin-right:15px;
}

To explain the idea:

  • Create elements, each will hold a one digit of the current 2 digits value;
  • Set a common bg image to all spans in CSS
  • Every second move each element's background-image left by -(witdh * number) px

While the listed above seems logic, the first problem you can see here is how to retrieve separately a JS time number (1 or 2 digits) keep leading zero if needed, and reference each digit to target the right element in HTML?

Let's start by splitting numbers:

35 == 3, 5 /// 0 == 0, 0 // this is an example of what we need.

var n  = 35;        // Set any 1 or 2 digit number.
var n1 = ~~(n/10);  // 3 //// ~~ "Double Bitwise NOT"
                                 // just instead of parseInt(time/10, 10).
var n2 = n%10;      // 5 //// %  "Mudulus operator" (reminder).

Example playground

JS Grouping

Now, how to group this two separated digits and say: "Hey you two are for my clock seconds!" ?
By simply putting them into an array! [3, 5], and for we'll have also minutes, hours and day - let's simply put all those arrays into an Object and assign a Key Name which will result in having an object like:

obj = {d:[7,4], h:[1,9], m:[2,9], s:[0,7]}

Reference to HTML

Having that Object and knowing that inside an for...in loop we can retrieve the Key name and the array value like eg: obj['d'][0] === 7 obj['d'][5] === 4

means that we'll need a for loop to retrieve the 0 and 1 to get the values in our array positions [pos0, pos1]
all inside a for...in loop that will get the KEY names : d, h, m, s

2pos x 4keyNames = 8 elements iterations/second

means that now we'll be able to target an ID element eg: #s0 and #s1
and all we need now is to retrieve the value and animate that element background by
-width * digit

Comments