<div class='spriteslider' id='spriteslider'>
  <div id='spritetarget'></div>
</div>

<p>Drag the box left/right to control the sprite's position.</p>
body {
  text-align: center;
  font: normal 12px sans-serif;
  background: #000000;
  color: #91E600;
}
.spriteslider {
  margin: 20px auto;
  padding: 60px;    
  width: 128px;
  background: #FCFEFC;
  border-radius: 5px;
}
#spritetarget {
  width: 128px;
  height: 128px;
  background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/29123/heart.png); /* horizontal spritesheet - image from http://preloaders.net */
  background-repeat: repeat-x;
}
// use a dummy element as the target since we don't really need anything visual to drag around
var spriteslider = document.createElement('div');
// the dummy element needs to be added to the DOM in latest Draggable
document.body.appendChild(spriteslider);

// attach all vars to the dummy element so globals aren't needed:
// element that initiates dragging
spriteslider.slider = document.getElementById('spriteslider');
// element with the sprite sheet to control
spriteslider.sprite = document.getElementById('spritetarget');
// size of each sprite frame
spriteslider.spritesize = 128;
// number of sprite frames - used to keep multiplier in a reasonable range
spriteslider.spritecount = 20;
// pixels to drag per sprite update
spriteslider.pixelsperincrement = 25;
// values used by the sprite changer
spriteslider.multiplier = spriteslider.lastmultiplier = 0;


// create the 360 degree slider
Draggable.create(spriteslider, {
  	type: 'x',
  trigger: spriteslider.slider,
  // reset the targets position after drag ends, so onDrag doesn't need to deal with an offset
  bounds: { minX:0, maxX:0, minY:0, maxY:0 },
  // don't need to slow down as you drag further away
	  edgeResistance: 0,
  cursor: 'e-resize',
  onDrag: function() {
    // there is an extra drag event fired on mouse up that has x = 0, so check this.isDragging to skip that last one
    if (this.isDragging) {
      var t = this.target; // the dummy div
      t.multiplier = Math.floor(this.x / t.pixelsperincrement) + t.lastmultiplier;
      TweenLite.set(t.sprite, { backgroundPosition: (-t.multiplier * t.spritesize) + "px 0"});
    }
  },
	  onDragEnd: function()	{
    // saves the current multiplier, and keeps multiplier small so that backgroundPosition doesn't end up too large for the browser to render
    var t = this.target; // the dummy div
    t.lastmultiplier = t.multiplier % t.spritecount;
  }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/utils/Draggable.min.js