Skip to content

Instantly share code, notes, and snippets.

Created November 11, 2014 02:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/238b06d3dfc996a1937a to your computer and use it in GitHub Desktop.
Save anonymous/238b06d3dfc996a1937a to your computer and use it in GitHub Desktop.
A Pen by Captain Anonymous.
<div id="progress-bar-1" style="width: 10%"></div>
var playoutSlider = function(e) {
var duration = 0;
var cue = 0;
var intro = 0;
var positionInt = 0;
var isSliding = false;
/** DOM ELEMENTS **/
var sliderContainer = document.createElement('div');
sliderContainer.className = 'playout-slider';
var cueSlider = document.createElement('div');
cueSlider.className = 'playout-slider-cue';
var cueHandle = document.createElement('div');
cueHandle.className = 'playout-handle';
var cueHandleCircle = document.createElement('div');
cueHandleCircle.className = 'playout-handle-circle';
cueHandleCircle.title = 'Drag to set the cue position';
cueHandle.appendChild(cueHandleCircle);
cueSlider.appendChild(cueHandle);
sliderContainer.appendChild(cueSlider);
var introSlider = document.createElement('div');
introSlider.className = 'playout-slider-intro';
var introHandle = document.createElement('div');
introHandle.className = 'playout-handle';
var introHandleCircle = document.createElement('div');
introHandleCircle.className = 'playout-handle-circle';
introHandleCircle.title = 'Drag to set the intro duration';
introHandle.appendChild(introHandleCircle);
introSlider.appendChild(introHandle);
sliderContainer.appendChild(introSlider);
var positionSlider = document.createElement('div');
positionSlider.className = 'playout-slider-position';
var positionSliderLine = document.createElement('div');
positionSliderLine.className = 'playout-slider-line';
positionSlider.appendChild(positionSliderLine);
var positionHandle = document.createElement('div');
positionHandle.className = 'playout-handle';
positionSlider.appendChild(positionHandle);
sliderContainer.appendChild(positionSlider);
/** HELPER FUNCTIONS **/
var calculatePositionFromSeek = function(e, slider) {
var result = e.clientX - getXOffset(e.currentTarget) + 3;
if (result > sliderContainer.offsetWidth) {
result = sliderContainer.offsetWidth;
}
slider.style.width = result + 'px';
return result / getPixelsPerSecond();
}
var getXOffset = function(e) {
var x = 0;
while (e) {
x += e.offsetLeft + e.clientLeft - e.scrollLeft;
e = e.offsetParent;
}
return x;
}
/** EVENT BINDINGS **/
var positionHandleDragStart = function() {
var positionInt;
if (!isSliding) {
isSliding = true;
var dragMove = function(e) {
positionInt = calculatePositionFromSeek(e, positionSlider);
return false;
}
var dragEnd = function(e) {
sliderContainer.dispatchEvent(new CustomEvent('seeked', {detail: {time: positionInt}}));
sliderContainer.removeEventListener('mousemove', dragMove);
window.removeEventListener('mouseup', dragEnd);
isSliding = false;
return false;
}
sliderContainer.addEventListener('mousemove', dragMove);
window.addEventListener('mouseup', dragEnd);
return false;
}
}
positionHandle.addEventListener('mousedown', positionHandleDragStart);
var introHandleDragStart = function() {
if (!isSliding) {
isSliding = true;
var dragMove = function(e) {
intro = calculatePositionFromSeek({clientX: e.clientX, currentTarget: introSlider}, introSlider);
return false;
}
var dragEnd = function(e) {
sliderContainer.dispatchEvent(new CustomEvent('introChanged', {detail: {time: intro}}));
sliderContainer.parentNode.parentNode.removeEventListener('mousemove', dragMove);
window.removeEventListener('mouseup', dragEnd);
isSliding = false;
return false;
}
sliderContainer.parentNode.parentNode.addEventListener('mousemove', dragMove);
window.addEventListener('mouseup', dragEnd);
return false;
}
}
introHandle.addEventListener('mousedown', introHandleDragStart);
var cueHandleDragStart = function() {
if (!isSliding) {
isSliding = true;
var dragMove = function(e) {
cue = calculatePositionFromSeek({clientX: e.clientX, currentTarget: cueSlider}, cueSlider);
return false;
}
var dragEnd = function(e) {
sliderContainer.dispatchEvent(new CustomEvent('cueChanged', {detail: {time: cue}}));
sliderContainer.parentNode.parentNode.removeEventListener('mousemove', dragMove);
window.removeEventListener('mouseup', dragEnd);
isSliding = false;
return false;
}
sliderContainer.parentNode.parentNode.addEventListener('mousemove', dragMove);
window.addEventListener('mouseup', dragEnd);
return false;
}
}
cueHandle.addEventListener('mousedown', cueHandleDragStart);
// Needs to go after drag handlers to ensure they set isSliding first
var clickHandler = function(e) {
if (!isSliding) {
calculatePositionFromSeek(e, positionSlider);
sliderContainer.dispatchEvent(new CustomEvent('seeked', {detail: {time: positionInt}}));
return false;
}
}
sliderContainer.addEventListener('mousedown', clickHandler);
var reset = function(newDuration, newCue, newIntro) {
duration = parseInt(newDuration);
cue = parseInt(newCue);
intro = parseInt(newIntro);
positionInt = 0;
redraw();
}
var getPixelsPerSecond = function() {
return (duration > 0 ? (sliderContainer.offsetWidth - 2)/duration : 0)
}
var position = function(newPosition) {
if (newPosition !== undefined) {
if (!isSliding) {
positionInt = newPosition;
redraw();
}
} else {
return positionInt;
}
}
var redraw = function() {
cueSlider.style.width = cue * getPixelsPerSecond() + 'px';
introSlider.style.width = intro * getPixelsPerSecond() + 'px';
positionSlider.style.width = positionInt * getPixelsPerSecond() + 'px';
}
var addEventListener = function(a, b, c) {
sliderContainer.addEventListener(a, b, c);
}
var removeEventListener = function(a, b, c) {
sliderContainer.removeEventListener(a, b, c);
}
//Attach the seekbar to the DOM
e.className = 'playout-slider-container';
e.appendChild(sliderContainer);
return {
reset: reset,
position: position,
addEventListener: addEventListener,
removeEventListener: removeEventListener
}
}
playoutSlider.prototype = {
constructor: playoutSlider
};
playoutSlider(document.getElementById('progress-bar-1'));
.playout-slider-container {
margin-top: 5px;
width: 100%;
height: 26px;
text-align: left;
}
.playout-slider-container .playout-slider {
background-color: #eee;
border: 1px solid #428bca;
border-radius: 3px;
width: 100%;
height: 100%;
position: relative;
cursor: pointer;
}
.playout-slider div {
display: inline-block;
position: absolute;
}
.playout-slider .playout-slider-cue,
.playout-slider .playout-slier-intro {
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
.playout-slider .playout-slider-cue {
background-color: #d9534f;
top: 0;
height: 100%;
}
.playout-slider .playout-slider-intro {
background-color: #5bc85c;
top: 3px;
height: calc(100% - 6px);
}
.playout-slider .playout-slider-position {
border-top: 12px solid rgba(66, 139, 202, 0.4);
border-bottom: 12px solid rgba(66, 139, 202, 0.4);
top: 0;
height: 4px;
}
.playout-slider .playout-slider-position .playout-slider-line {
background-color: #2376bb;
height: 4px;
width: 100%;
position: absolute;
top: -2px;
}
background->.playout-slider .playout-slider-position .playout-handle {
position: absolute;
right: 0;
top: -13px;
height: 26px;
width: 3px;
background-color: #0a5a9c;
}
.playout-slider:hover .playout-slider-position .playout-handle {
right: -2px;
width: 7px;
}
.playout-slider .playout-slider-intro .playout-handle {
position: absolute;
right: 0;
top: -3px;
height: 24px;
width: 2px;
background-color: #5bc85c;
}
.playout-slider .playout-slider-intro .playout-handle {
position: absolute;
right: 0;
top: -3px;
height: 24px;
width: 2px;
background-color: inherit;
}
.playout-slider .playout-slider-intro:hover .playout-handle,
.playout-slider .playout-slider-intro:active .playout-handle {
height: 30px;
}
.playout-slider .playout-slider-intro .playout-handle .playout-handle-circle {
width: 10px;
height: 10px;
position: absolute;
bottom: -8px;
left: -4px;
}
.playout-slider .playout-slider-cue .playout-handle,
.playout-slider .playout-slider-cue .playout-handle {
position: absolute;
right: 0;
height: 30px;
width: 2px;
top: -5px;
}
.playout-slider .playout-slider-intro:hover .playout-handle .playout-handle-circle,
.playout-slider .playout-slider-intro:active .playout-handle .playout-handle-circle {
border: 2px solid #5bc85c;
border-radius: 5px;
}
.playout-slider .playout-slider-cue:hover .playout-handle,
.playout-slider .playout-slider-cue:active .playout-handle {
background-color: inherit;
}
.playout-slider .playout-slider-cue .playout-handle .playout-handle-circle {
width: 10px;
height: 10px;
position: absolute;
top: -8px;
left: -4px;
}
.playout-slider .playout-slider-cue:hover .playout-handle .playout-handle-circle,
.playout-slider .playout-slider-cue:active .playout-handle .playout-handle-circle {
border: 2px solid #d9534f;
border-radius: 5px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment