A Pen by Captain Anonymous on CodePen.
Created
November 11, 2014 02:06
-
-
Save anonymous/238b06d3dfc996a1937a to your computer and use it in GitHub Desktop.
A Pen by Captain Anonymous.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="progress-bar-1" style="width: 10%"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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