Scriptaculous slider trick

Yesterday I was looking at the Scriptaculous library, in particular the slider bar. I had used it once before with some success, using a graphic for the track and gripper. But that's was boring! What I wanted was to see the bar fill up with colour when it was slide. Something like this:

Slider demo

I hadn't seen anything like this around (not saying it hasn't been done, just that I hadn't seen it!), so after a bit of playing I found out it was actually very easy to create. And this is how I did it...

All it really does is use a handy little trick with transparent PNG images and background-image positions. You can find details of what I mean in this handy article by Dave Stone, over at Bare Naked App.

So basically I have my slider gripper (or handle), which has a transparent background:

Slider gripper

And the slider track, which has an opaque white background but is transparent where I want the colour to show through (thumbnail shown, but links through to full size image):

Slider track

And then I have the background image, which is essentially double the size of the track and has one half in off-white and one in green (thumbnail shown, but links through to full size image):

Slider background

The XHTML used for the slider looks like this:

HTML:
  1. <div id="slider">
  2.     <div id="slider-bar">
  3.         <div id="slider-handle"><p id="percent"></p></div>
  4.     </div>
  5. </div>

The CSS looks like this:

CSS:
  1. #slider, #slider-bar, #slider-handle {
  2.     border: 0;
  3.     padding: 0;
  4.     margin: 0;
  5. }
  6. #slider {
  7.     width: 300px;
  8.     height:42px;
  9.     background: url(img/bg.gif) no-repeat -300px;
  10.     margin-left: 42px;
  11. }
  12. #slider-bar {
  13.     width:300px;
  14.     height:42px;
  15.     background: url(img/track.png) no-repeat;
  16. }
  17. #slider-handle {
  18.     width:42px;
  19.     height:42px;
  20.     cursor:move;
  21.     background: url(img/gripper.png) no-repeat;
  22. }
  23. #percent {
  24.     font-size: 75%;
  25.     font-family: arial;
  26.     font-weight: bold;
  27.     text-align: center;
  28.     padding-top: 1.1em;
  29. }

And finally, the Javascript looks like this:

JAVASCRIPT:
  1. <script type="text/javascript">
  2. // <![CDATA[
  3. var hWidth, bWidth;
  4.  
  5. function setBgPos(v) {
  6.     var off = v * hWidth;
  7.     var pos = -bWidth + (v * bWidth);
  8.     $('slider').setStyle({backgroundPosition: Math.round(pos - off) + 'px'});
  9. }
  10.  
  11. function setSlideOutput(v) {
  12.     $('percent').innerHTML = Math.round(v * 100) + '%';
  13. }
  14.  
  15. Event.observe(window, 'load', function() {
  16.     hWidth = $('slider-handle').getWidth();
  17.     bWidth = $('slider-bar').getWidth();
  18.     var slide = new Control.Slider('slider-handle', 'slider-bar', {
  19.         sliderValue: 0.25,
  20.         onSlide:
  21.             function(v) {
  22.                 setBgPos(v);
  23.                 setSlideOutput(v);
  24.             },
  25.         onChange:
  26.             function(v) {
  27.                 setBgPos(v);
  28.                 setSlideOutput(v);
  29.             }
  30.     });
  31.     setBgPos(slide.value);
  32.     setSlideOutput(slide.value);
  33. });
  34. // ]]>
  35. </script>

You may notice the offset value, off. I'm using this because in my experiment the slider handle doesn't fully cover the bar (nor did I want it to), so I cannot have the background image colour go fully across the track. I had to incrementally offset it depending on the position and size of the handle.

And that's it! Pretty darned easy, but looks really neat. You can see it in action at http://dev.amnuts.com/slider/.

1 Response to “Scriptaculous slider trick”


  1. 1 Andy

    I thought this was a little dodgy on Safari; the track image wouldn’t update and the percentage value wouldn’t display. In the end it turned out to be the version of Safari I was using not having Javascript 1.5, which the .toFixed() method requires. Changing that to use Math.round() fixes the issues in Safari (version < 2.0).

    I’ve updated the code to reflect this change.

Leave a Reply

You must login to post a comment.