Volume Implementation
by sammy
HTML
<div class='track'><div class='thumb'></div></div>
<p>
In this example, we only add the distance of the drag to the current thumbs position. What we need to record when the user starts the drag (mousedown) is the the position of the cursor (startClientY) and the position of the thumb (startThumbY). Then as the user drags (mousemove), we calculate the distance of the cursor by subtracting the start postion (startClientY) from the current position (event.clientY). We then add this distance to the thumbs position we recored (startThumbY). Finally, we disabled the dragging (isDraggin = false) when the user releases the mouse button anywhere in the window (mouseup).
</p>
<p>
Things you might want to note is that we limit the thumb's position to the tracks height minus the thumb's height. We can divide the thumb's position (thumbY) by this track boundary (trackHeight) to get a percentage for our volume. Sense we want the volume to be at 100% when the thumb is at the top of the track (top:0px), we should "invert" the percentage value by subtracting the thumb's position (thumbY) from the track's height (trackHeight), then do our division.
</p>
<p>
I hope this helps to provide the mose basic way to implement a volume control in any application. Few things to remember: 1) always disabled the drag with a mouseup event on the WINDOW, not the thumb or track or any other element. 2) Add the drag distance to the thumb's position, don't set the thumbs position to the cursors position. This is bad because the user cannot make a small change without getting their cursor in the right position before dragging.
</p>
<p>
You should probably implement custom drag events for all elements, just to make dragging easier to implement on all elements. See <a href='http://threedubmedia.com/code/event/drag'>this jQuery plugin</a> if you're using jQuery. If you're not using jQuery, you can still get some ideas from this.
</p>
CSS
.track {
background: lightgrey;
width: 10px;
height: 100px;
position: relative;
cursor: default;
}
.thumb {
position: absolute;
top:0px;
background: red;
width: 10px;
height: 10px;
text-indent: 20px;
}
p {
margin: 10px 0px;
font-family: arial;
}
JavaScript
var isDragging = false, startClientY;
function changeVolume(thumbY)
{
var trackHeight = $('.track').height() - $('.thumb').height();
thumbY = Math.max(Math.min(thumbY, trackHeight), 0);
var percentage = Math.floor((trackHeight - thumbY)/trackHeight * 100);
$('.thumb')
.css('top', thumbY +"px")
.text(percentage +"%");
}
$('.thumb')
.mousedown(function(event){
isDragging = true;
startClientY = event.clientY;
startThumbY = parseInt($(this).css('top'));
return false; // Prevents text selection
});
$('.track')
.mousedown(function(event){
isDragging = true;
startClientY = event.clientY;
startThumbY = event.clientY - $('.track').offset().top - $('.thumb').height()/2;
changeVolume(startThumbY);
return false; // Prevents text selection
});
$(window)
.mousemove(function(event){
if (isDragging)
{
var thumbY = startThumbY + event.clientY - startClientY;
changeVolume(thumbY);
return false; // Prevents text selection
}
})
.mouseup(function(){
isDragging = false;
});