Created
July 23, 2015 19:47
-
-
Save mattkelley/4eee7bc61b645ef0f56b to your computer and use it in GitHub Desktop.
Revisions
-
Matt Kelley created this gist
Jul 23, 2015 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,138 @@ var on = function(items, scope) { items.forEach(function(item) { return item.e.map(function(e) { item.context.addEventListener(e,item.fn,false) }) }) } var off = function(items) { items.forEach(function(item) { return item.e.map(function(e) { item.context.removeEventListener(e,item.fn,false) }) }) } // move the element to a percentage point var to = function(el, percent) { // This is for sanity but also for visual. The playhead shouldn't leave the progress bar. var clamp = Math.min(Math.max(percent, 0.2), 99.8); // Convert this into matrices stuff later ['webkitTransform', 'MozTransform', 'msTransform', 'transform'].forEach(function(v) { el.style[v] = 'translateX(' + clamp + '%)'; }); } // calculate the percentage point var percentage = function(el, event) { var x = (event.touches) ? event.touches[0].clientX : event.clientX; var position = x - el.getBoundingClientRect().left; var percentage = 100 * position / el.offsetWidth; return Math.min(Math.max(percentage, 0), 100); } /** * Range slider * Creates a simple UI slider for scrubbing video or volume * @param {Element} el */ function Range(el) { // store passed element this._el = el; // current percentage of the range element this._position = 0; // amount of move events in the current range adjustment this._count = 0; // create elements, and the event configuration this.create(); }; // Enable the range slider events Range.prototype.enable = function() { on([this._e.start]); }; // Disable the range slider events Range.prototype.disable = function() { off([this._e.start]); }; // Get the range current position Range.prototype.get = function() { return this._position; }; // Set the range position Range.prototype.set = function() { this._position = percent; to(this._time, this._position); }; // Handle touchstart and mousedown events Range.prototype._start = function() { event.stopPropagation(); on([this._e.move, this._e.stop]); this.trigger('begin', {type: 'begin', srcEvent: event, percent: this._position}); if (this._position !== percentage(this._bar, event)) { this.move(event); } }; // Handle touchmove and mousemove events Range.prototype._move = function() { event.stopPropagation(); this._position = percentage(this._bar, event); to(this._time, this._position); this.trigger('move', {type: 'move', srcEvent: event, count: ++this._count, percent: this._position}); }; // Handle touchend and mouseup events Range.prototype._stop = function() { event.stopPropagation(); off([this._e.move, this._e.stop]); this.trigger('end', {type: 'end', srcEvent: event, percent: this._position }); this._count = 0; }; // Destroy the Range slider elements and remove event listeners Range.prototype.destroy = function() { off([this._e.start, this._e.move, this._e.stop]); this._bar.removeChild(this._time); this._el.removeChild(this._bar); this._el.classList.remove('ivp-control-progress'); }; // Create the Range markup and event configuration Range.prototype.create = function() { // Bar is the outer element always visibile this._bar = document.createElement('div'); this._bar.className = 'ivp-progress-bar'; // Time is the inner element which slides this._time = document.createElement('div'); this._time.className = 'ivp-progress-time'; this._bar.appendChild(this._time); // @NOTE modifying passed element here - not sure if I like this or not this._el.classList.add('ivp-control-progress'); this._el.appendChild(this._bar); var _this = this; this._e = { start: { context: this._bar, e: ['mousedown', 'touchstart'], fn: function() { _this._start.apply(_this, arguments); } }, move: { context: document, e: ['mousemove', 'touchmove'], fn: function() { _this._move.apply(_this, arguments); } }, stop: { context: document, e: ['mouseup', 'touchend'], fn: function() { _this._stop.apply(_this, arguments) } } } }; // Export the Range class as default export default Range;