Gavin’s Odd Bits of Code

2008-04-07 (Mon)

CSS/JavaScript Animated Odometer

Filed under: Web — Gavin Brock @ 10:14 pm
Tags: , ,

As part of the Street View saver page, I thought it would be fun to see how far you have “driven“. So I set about finding an odometer. This proved harder than I expected since most of what was out there were static, image based web-counters.

So I set about some CSS hacking and came up with this:
Odometer screen shot

This is entirely CSS and Javascipt based and fairly browser neutral (only fairly common one missing is IE 6 – bleagh).

Full details, including API, here.

Zip download here.

Update: 2009/04/07

Two odometers should work too:

<script src=”odometer.js” type=”text/javascript”></script>
<script type=”text/javascript”>
//<![CDATA[
var n = 9999999998;
var m = 10;
var myOdometer1, myOdometer2;
function run () {
var div1 = document.getElementById("odometerDiv1");
var div2 = document.getElementById("odometerDiv2");
myOdometer1 = new Odometer(div1, {value: n, digits: 10, tenths: true});
myOdometer2 = new Odometer(div1, {value: m, digits: 10, tenths: true});
update1();
update2();
}

function update1 () {
n=n+0.0025
myOdometer1.set(n);
setTimeout("update1()", 50);
}
function update2 () {
m=m-0.001
myOdometer2.set(m);
setTimeout("update2()", 100);
}
//]]>
</script>

<body onload=”run()” >
<div id=”odometerDiv1″ style=”width:100%;”></div>
<hr>
<div id=”odometerDiv2″ style=”width:100%;”></div>

About these ads

26 Comments »

  1. Very cool!

    There is a small bug in the HTML file in the zip file. The SRC for the SCRIPT tag that imports odometer.js should be “odometer.js”, not “/odometer.js”.

    -Mark

    Comment by Mark Sheldon — 2008-09-19 (Fri) @ 12:19 am | Reply

  2. Yup – that’s bad. I’ve fixed it and made a “odometer-1.0b.zip” and updated the link above.

    Thanks for pointing it out!!

    Gavin

    Comment by brockgr — 2008-09-19 (Fri) @ 11:12 am | Reply

  3. Hi,

    This is a great script! You did a great job!

    I am seeing somthing strange. I notice that the odometer runs at differnt rates with differnt browsers. The same odometer settings runs faster in Firefox then in IE. What to you think is the reason for this?

    Thanks,
    Jerome

    Comment by Jerome — 2008-10-07 (Tue) @ 2:42 pm | Reply

  4. On the demo page (http://www.brock-family.org/gavin/software/web/odometer.html), the updates are triggered by the following function:

    function update () {
    n=n+0.0025
    myOdometer.set(n);
    setTimeout(“update()”, 0);
    }

    The setTimeout tells the Javascript engine to call the update() function again after 0ms (which means “whenever you have a moment”). Depending on your browser/computer, this will vary. Each update() increments the counter by the number 0.0025.

    If you want a more consistent timing, you should increase the timeout and “n” increment. e.g. n=n+1.0 with a timeout of 1000 will give you one second updates. Of course you will take a hit on the smoothness of the animation (1 frame per second is not really animation).

    Even this though will not be accurate over long times – the 1 second is not exactly 1 second when you take into account the time used to redraw the odometer. For the most accurate solution, you should have a timer repeat very quickly and then base your increment of n relative to a call to the system clock (using date). Obviously this is nowhere near as trivial.

    Gavin

    Comment by brockgr — 2008-10-07 (Tue) @ 2:57 pm | Reply

  5. Hi Gavin,

    Fun script. I have scaled the odometer down to fit into a sidebar. It looks great on the Mac in firefox and Safari. The numbers in IE7 however are now gray instead of bright white. Can you help?

    thanks,

    Bonnie

    Comment by Bonnie — 2008-10-31 (Fri) @ 10:16 pm | Reply

  6. This is probably an issue with the semi-transparent overlays to make the gradients. I’ll have a look when I get a windows box to hand.

    Comment by brockgr — 2008-11-03 (Mon) @ 10:50 pm | Reply

  7. Thanks for the script. Is it possible to put two odometers on the same page?

    Comment by David — 2009-01-09 (Fri) @ 7:31 pm | Reply

  8. I added a two odometer example to the post above (since I can’t put HTML in the comments!)

    Comment by brockgr — 2009-04-07 (Tue) @ 10:11 am | Reply

  9. You can also notice that the code runs faster on Google Chrome. As it is based on a timeout you can’t expect it to run at the same speed on every setup ( browser / pc ).

    Looks great though :)

    Comment by Tiveau — 2009-04-08 (Wed) @ 3:29 am | Reply

    • The timing thing is because the timeout is set to 0ms, so the loop runs as fast as possible. This is fun since it gives a visual indication of the javascript/rendering performance of the browser, and that is why Chrome appears so fast.

      Comment by brockgr — 2009-04-08 (Wed) @ 8:58 am | Reply

  10. Is it possible for the counter to count down instead of up

    Comment by jonathan — 2009-04-14 (Tue) @ 9:29 pm | Reply

    • Jonathan, since you use the odometer.set(n) function to set the value on the counter to n, you can choose whether you want to increment or decrement the counter by how you calculate n. In the two counter example above, one counter goes up, and the other goes down.

      Comment by brockgr — 2009-04-14 (Tue) @ 10:52 pm | Reply

  11. Hello,

    How can I get the counter to be placed on the same line as the text in your example?

    use display:inline for the div does not seem to do the trick.

    Thanks & regards,
    Robin

    Comment by Robin — 2009-08-28 (Fri) @ 8:31 pm | Reply

  12. Just forget the above. But can you extend the odometer to have more digits behind the comma?

    Thanks & regards,
    Robin

    Comment by Robin — 2009-09-01 (Tue) @ 10:44 pm | Reply

  13. Regarding alignment – that is all CSS magic. I’m sure it’s possible – but would take a lot of head scratching.

    The extra fractional digits is a great idea. I guess I could change the “tenths” option to take an integer value instead of a boolean. I’ll have a go at the code when I have some time.

    Comment by brockgr — 2009-09-06 (Sun) @ 12:07 pm | Reply

  14. can it run for some time lets say 500 then stop to a static value 500.1

    Comment by Tikka — 2009-12-16 (Wed) @ 1:39 pm | Reply

  15. Tikka, You can really do whatever you like – the odometer just shows the value you tell it to show. What values you choose is up to you (and your other code).

    Comment by brockgr — 2010-02-04 (Thu) @ 8:40 am | Reply

  16. What if wanted to put a $ sign in the first block of number. Any ideas on how?

    Comment by TheEleven — 2010-02-05 (Fri) @ 3:18 am | Reply

  17. Tried downloading and putting it all in a test.html file (with the necessary subfolders.

    Mine doesnt show on F/F 8.x

    Basically I am looking for a manual odometer of 6 fields (100000) where I could define the variable as 12488 (miles), then next month, manually change it to 55,678 miles..etc..

    Is there a simpler js that could do this.

    Thanks

    Comment by Bogeyplay — 2010-02-26 (Fri) @ 5:18 pm | Reply

  18. is there any way you can alter the number images? For instance, I love the function, but would like to replace the looks of the numbers…

    Comment by Anthony — 2010-03-11 (Thu) @ 1:39 am | Reply

  19. Second thing, can you put commas in between numbers?

    Comment by Anthony — 2010-03-11 (Thu) @ 2:20 am | Reply

  20. Thanks for the great script.
    I slightly adapted it to have a variable number of decimals, not just tenths.
    Here are the changes :
    1) Replace
    this.tenths = 0;
    by
    this.decimals = 0;

    2) Replace :
    if (this.tenths) inVal = inVal * 10;
    by
    inVal = inVal * Math.pow(10, this.decimals);

    3) Replace :
    if (this.tenths) {
    by
    for (var i = 1; i <= this.decimals; i++) {

    4) in the next 4 lines, replace 1 by i, as follows :
    digitInfo[this.digits - 1]…
    by
    digitInfo[this.digits - i]…

    Of course, init code must now specify :
    decimals:
    instead of :
    tenths: [true|false]

    Comment by Vicne — 2011-06-05 (Sun) @ 7:41 am | Reply

  21. I’m getting very unpredictable results with this.
    In the initial setup of the myOdometer object, I can set the correct starting value, such as 1.2, and it displays correctly.
    However, when I do myOdometer.set(val) afterwards, the results are almost random. 1.7 displays as 2.8, both 2.3 and 2.4 display as 2.4, etc.
    You can see what I’m talking about at oilcalc.mememellc.com

    Comment by Tim — 2012-06-27 (Wed) @ 4:46 am | Reply

  22. thanks! This was exactly was I needed for a personal project, very nice. I’ve wrapped a slightly modified version up into a quick WordPress widget plugin, For some reason was having problems with the text alignment on some themes I tried it with until I specifically added line-height to the digit elements, I have a few more tweaks to add but an initial version is available here if anybody wants it http://strawberryjellyfish.com/wordpress-plugin-jellyfish-counter-widget/

    Comment by digitalllama — 2013-01-12 (Sat) @ 3:58 pm | Reply

  23. is there a way to just have the counter increase and not reset on page reload or refresh… ex: i am looking for a counter that just continues counting even if the user is off the site…

    Comment by oscar — 2013-02-05 (Tue) @ 5:30 am | Reply

  24. I’m using the odometer in a case where I don’t want to show transitions, just the current value, so I always set it to an integer value. In this case, and maybe in others, I think there’s a bug in the setDigitValue() method: if the digit changes, then the digitA and digitB style top values need to be set even if the px hasn’t changed.

    So, I created a new variable just before the if (val != di.last_val) clause:

    var fSetPx = px != di.last_px;

    Inside that clause, I set fSetPx = true, so it gets set if either the px or the val change.

    Then the following if changes from if (px != di.last_px) to if (fSetPx).

    Thanks for sharing your code!

    Best regards,

    Comment by Tom Saxton — 2013-05-02 (Thu) @ 8:14 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: