 <p>On a second reading, I think I misunderstood your question, so here's an updated version:</p> <p><a href="http://jsfiddle.net/HSMfR/4/">http://jsfiddle.net/HSMfR/4/</a></p> <pre><code>$(function () { var $canvas = $('#canvas'), ctx = $canvas[0].getContext('2d'), offset = $canvas.offset(), draw, handle; handle = { color: '#666', dim: { w: 20, h: canvas.height }, pos: { x: 0, y: 0 } }; $canvas.on({ 'mousedown.slider': function (evt) { var grabOffset = { x: evt.pageX - offset.left - handle.pos.x, y: evt.pageY - offset.top - handle.pos.y }; // simple hit test if ( grabOffset.x &gt;= 0 &amp;&amp; grabOffset.x &lt;= handle.dim.w &amp;&amp; grabOffset.y &gt;= 0 &amp;&amp; grabOffset.x &lt;= handle.dim.h ) { $(document).on({ 'mousemove.slider': function (evt) { handle.pos.x = evt.pageX - offset.left - grabOffset.x; // prevent dragging out of canvas if (handle.pos.x &lt; 0) { handle.pos.x = 0; } if (handle.pos.x + handle.dim.w &gt; canvas.width) { handle.pos.x = canvas.width - handle.dim.w; } //handle.pos.y = evt.pageY - offset.top - grabOffset.y; }, 'mouseup.slider': function () { $(document).off('.slider'); } }); } } }); draw = function() { var val = (100 * (handle.pos.x / (canvas.width - handle.dim.w))).toFixed(2) + '%'; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fillStyle = handle.color; ctx.fillRect(handle.pos.x, handle.pos.y, handle.dim.w, handle.dim.h); ctx.textBaseline = 'hanging'; ctx.font = '12px Verdana'; ctx.fillStyle = '#333'; ctx.fillText(val, 4, 4); ctx.fillStyle = '#fff'; ctx.fillText(val, 3, 3); }; setInterval(draw, 16); }); </code></pre> <hr> <p><strong>prev version</strong>:</p> <p>Very simple solution to extend upon:</p> <p><a href="http://jsfiddle.net/HSMfR/">http://jsfiddle.net/HSMfR/</a></p> <pre><code>$(function () { var ctx = $('#canvas')[0].getContext('2d'), $pos = $('#pos'), draw; draw = function() { var x = ($pos.val() / 100) * (ctx.canvas.width - 20); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fillStyle = 'black'; ctx.fillRect(x, 0, 20, 20); }; setInterval(draw, 40); }); </code></pre>