You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
10 KiB
310 lines
10 KiB
/*! |
|
jQuery timebar plugin |
|
@name timebar.js |
|
@author pulkitchadha (pulkitchadha27@gmail.com] |
|
@version 1.0 |
|
@date 28/03/2018 |
|
@category jQuery Plugin |
|
@copyright (c) 2018 pulkitchadha (pulkitchadha) |
|
@license Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. |
|
*/ |
|
(function ($) { |
|
|
|
var timebar, defaultOptions, __bind; |
|
|
|
__bind = function (fn, me) { |
|
return function () { |
|
return fn.apply(me, arguments); |
|
}; |
|
}; |
|
|
|
// Plugin default options. |
|
defaultOptions = { |
|
//properties |
|
element: null, |
|
totalTimeInSecond: 60, |
|
cuepoints: [], |
|
width: '1000px', |
|
globalPageX: 0, |
|
selectedTime: 0, |
|
multiSelect: false, |
|
showCuepoints: true, |
|
stepBars: 100, |
|
timeIntervals: 10, |
|
// events |
|
barClicked: null, |
|
cuepointClicked: null, |
|
|
|
//Currently, Not supported |
|
|
|
// life cycle methods |
|
beforeCreate: null, |
|
created: null, |
|
beforeMount: null, |
|
mounted: null, |
|
beforeUpdate: null, |
|
updated: null, |
|
// hooks |
|
beforeAddCuepoint: null, |
|
afterAddCuepoint: null, |
|
beforeUpdateCuepoint: null, |
|
afterUpdateCuepoint: null, |
|
beforeDeleteCuepoint: null, |
|
afterDeleteCuepoint: null, |
|
}; |
|
|
|
timebar = (function (options) { |
|
|
|
function timebar(element, options) { |
|
var self = this; |
|
|
|
// Extend default options. |
|
$.extend(true, this, defaultOptions, options); |
|
|
|
this.element = element; |
|
|
|
// Bind methods. |
|
this.init = __bind(this.init, this); |
|
this.update = __bind(this.update, this); |
|
this.getSelectedTime = __bind(this.getSelectedTime, this); |
|
this.setSelectedTime = __bind(this.setSelectedTime, this); |
|
this.getTotalTime = __bind(this.getTotalTime, this); |
|
this.setTotalTime = __bind(this.setTotalTime, this); |
|
this.getWidth = __bind(this.getWidth, this); |
|
this.setWidth = __bind(this.setWidth, this); |
|
this.getActualWidth = __bind(this.getActualWidth, this); |
|
this.formatTime = __bind(this.formatTime, this); |
|
this.addCuepoints = __bind(this.addCuepoints, this); |
|
this.deleteSelectedCuepoints = __bind(this.deleteSelectedCuepoints, this); |
|
this.updateSelectedCuepoint = __bind(this.updateSelectedCuepoint, this); |
|
this.showHideCuepoints = __bind(this.showHideCuepoints, this); |
|
|
|
// When user clicks on timebar |
|
$(this.element).on('click', '.step', function (event) { |
|
self.setSelectedTime($(this).data("time")); |
|
|
|
if (typeof self.barClicked === 'function') { |
|
self.barClicked.call(this, self.getSelectedTime()); |
|
} |
|
}); |
|
|
|
// Listen to events |
|
$(this.element).on('click', '.steps-bar', function (event) { |
|
self._barClicked(this, event, self); |
|
}); |
|
|
|
$(this.element).on("click", '.pointer', function () { |
|
self._cuepointClicked(this, self); |
|
}); |
|
|
|
}; |
|
|
|
// Method for updating the plugins options. |
|
timebar.prototype.update = function (options) { |
|
$.extend(true, this, options); |
|
}; |
|
|
|
// methods |
|
timebar.prototype.getSelectedTime = function () { |
|
return this.selectedTime; |
|
}; |
|
timebar.prototype.setSelectedTime = function (time) { |
|
if (!time && time !== 0) throw new Error('please pass the valid time'); |
|
|
|
this.selectedTime = parseInt(time); |
|
return this.timebarInstance; |
|
}; |
|
timebar.prototype.getTotalTime = function () { |
|
return this.totalTimeInSecond; |
|
}; |
|
timebar.prototype.setTotalTime = function (time) { |
|
if (!time) throw new Error('please pass the valid time'); |
|
|
|
this.totalTimeInSecond = parseInt(time); |
|
return this.timebarInstance; |
|
}; |
|
timebar.prototype.getWidth = function () { |
|
return this.width; |
|
}; |
|
timebar.prototype.setWidth = function (width) { |
|
if (!width) throw new Error('please pass the valid width'); |
|
|
|
this.width = width; |
|
width = this.getActualWidth() + 57; |
|
$(".timeline-cover").css('width', width + 'px'); |
|
return this.timebarInstance; |
|
}; |
|
timebar.prototype.getActualWidth = function () { |
|
let width = this.width; |
|
width = parseInt(width.replace(/px|%/g, '')); |
|
return width; |
|
} |
|
timebar.prototype.getCuepoints = function () { |
|
return this.cuepoints; |
|
} |
|
timebar.prototype.formatTime = function (sec_num) { |
|
return this.toDuration(sec_num); |
|
} |
|
timebar.prototype.addCuepoints = function (cuepoint) { |
|
if (!cuepoint) throw new Error('please pass the valid time'); |
|
|
|
cuepoint = parseInt(cuepoint); |
|
|
|
if (!this.cuepoints.includes(cuepoint)) { |
|
this.cuepoints.push(cuepoint); |
|
this.markCuepoints(cuepoint); |
|
} else { |
|
throw new Error('Cuepoint already exists'); |
|
} |
|
|
|
return this.timebarInstance; |
|
} |
|
timebar.prototype.deleteSelectedCuepoints = function () { |
|
var cuepoints = this.cuepoints; |
|
var selectedCuepoints = []; |
|
|
|
$(".pointerSelected").each(function () { |
|
var id = $(this).attr("id"); |
|
selectedCuepoints.push(parseInt(id)); |
|
}); |
|
|
|
if (selectedCuepoints.length) { |
|
this.cuepoints = cuepoints.filter((val) => !selectedCuepoints.includes(val)); |
|
$(".pointerSelected").remove(); |
|
} else { |
|
throw new Error('No Cuepoint is selected'); |
|
} |
|
|
|
return this.timebarInstance; |
|
} |
|
timebar.prototype.updateSelectedCuepoint = function (cuepoint) { |
|
var selectedCuepoints = []; |
|
|
|
$(".pointerSelected").each(function () { |
|
var id = $(this).attr("id"); |
|
selectedCuepoints.push(parseInt(id)); |
|
}); |
|
|
|
if (selectedCuepoints.length > 1) throw new Error('Please select only one cuepoint to update'); |
|
|
|
this.deleteSelectedCuepoints(); |
|
|
|
this.addCuepoints(cuepoint); |
|
|
|
return this.timebarInstance; |
|
} |
|
timebar.prototype.showHideCuepoints = function (show) { |
|
if (!show) throw new Error('please pass a valid value'); |
|
|
|
this.parseBoolean(show) ? $(".pointer").show() : $(".pointer").hide(); |
|
|
|
return this.timebarInstance; |
|
} |
|
|
|
// Main method. |
|
timebar.prototype.init = function () { |
|
let data = `<div class='timeline-cover'> |
|
<div id='draggable'></div> |
|
<div class='timeline-bar'> |
|
<div class='steps-bar clearfix'></div> |
|
</div> |
|
</div>`; |
|
|
|
$(this.element).append(data); |
|
|
|
this.setWidth(this.width); |
|
|
|
let timeDivison = this.totalTimeInSecond / this.stepBars; |
|
let time = 0; |
|
|
|
// mark bars |
|
for (let i = 0; i <= this.stepBars; i++) { |
|
$(".steps-bar").append(`<div class="step" data-time=${time}><span class="step-border"></span></div>`); |
|
time = time + timeDivison; |
|
} |
|
|
|
let markTimeDivison = this.totalTimeInSecond / this.timeIntervals; |
|
|
|
// mark time intervals |
|
for (let i = 0; i <= this.timeIntervals; i++) { |
|
var time = this.toDuration(Math.round(markTimeDivison * i)); |
|
var pos = i * 10 + 1; |
|
$(`.step:nth-child(${pos})`).append(`<span class="time-instant">${time}</span>`); |
|
} |
|
|
|
this.markCuepoints(this.cuepoints); |
|
|
|
if (!this.showCuepoints) { |
|
$(".pointer").hide(); |
|
} |
|
}; |
|
|
|
timebar.prototype.toDuration = function (sec_num) { |
|
let hours = Math.floor(sec_num / 3600); |
|
let minutes = Math.floor((sec_num - (hours * 3600)) / 60); |
|
let seconds = sec_num - (hours * 3600) - (minutes * 60); |
|
if (hours < 10) { |
|
hours = "0" + Math.round(hours); |
|
} |
|
if (minutes < 10) { |
|
minutes = "0" + Math.round(minutes); |
|
} |
|
if (seconds < 10) { |
|
seconds = "0" + Math.round(seconds); |
|
} |
|
var time = (hours == 0) ? minutes + ':' + seconds : hours + ':' + minutes + ':' + seconds; |
|
return time; |
|
} |
|
|
|
timebar.prototype.markCuepoints = function (cuepoints = []) { |
|
var options = this; |
|
var cuepointArr = Array.isArray(cuepoints) ? cuepoints : [cuepoints]; |
|
|
|
$.each(cuepointArr, function (i, time) { |
|
var animateLeft = (time * 100) / options.totalTimeInSecond; |
|
$(".timeline-bar").append(`<div class="pointer" style="left:${animateLeft}%" data-time="${time}"></div>`); |
|
}); |
|
} |
|
|
|
timebar.prototype._barClicked = function (element, event, self) { |
|
var offset = $(element).offset(); |
|
var offsetLeft = (event.pageX - offset.left); |
|
|
|
$('.pointer').removeClass("pointerSelected"); |
|
|
|
$("#draggable").css({ |
|
left: `${offsetLeft}px` |
|
}); |
|
}; |
|
timebar.prototype._cuepointClicked = function (element, self) { |
|
$(element).hasClass("pointerSelected") ? $(element).removeClass("pointerSelected") : $(element).addClass("pointerSelected"); |
|
|
|
self.setSelectedTime($(element).data("time")); |
|
|
|
if (typeof self.pointerClicked === 'function') { |
|
self.pointerClicked.call(element, self.getSelectedTime()); |
|
} |
|
} |
|
|
|
timebar.prototype.parseBoolean = function (val) { |
|
return (val.toLowerCase() === 'true'); |
|
} |
|
|
|
return timebar; |
|
})(); |
|
|
|
$.fn.timebar = function (options) { |
|
// Create a timebar instance if not available. |
|
if (!this.timebarInstance) { |
|
this.timebarInstance = new timebar(this, options || {}); |
|
} else { |
|
this.timebarInstance.update(options || {}); |
|
} |
|
|
|
// Init plugin. |
|
this.timebarInstance.init(); |
|
|
|
// return jQuery object to maintain chainability. |
|
return this.timebarInstance; |
|
}; |
|
})(jQuery); |