|
|
|
@ -1,11 +1,16 @@
@@ -1,11 +1,16 @@
|
|
|
|
|
String.prototype.toHHMMSS = function() { |
|
|
|
|
(function () { |
|
|
|
|
if (typeof NodeList.prototype.forEach === "function") return false; |
|
|
|
|
NodeList.prototype.forEach = Array.prototype.forEach; |
|
|
|
|
})(); |
|
|
|
|
|
|
|
|
|
String.prototype.toHHMMSS = function(leadZero) { |
|
|
|
|
let sec_num = parseInt(this, 10); |
|
|
|
|
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" + hours; |
|
|
|
|
if(minutes < 10) minutes = minutes; |
|
|
|
|
if(minutes < 10) minutes = leadZero ? "0" + minutes : minutes; |
|
|
|
|
if(seconds < 10) seconds = "0" + seconds; |
|
|
|
|
return minutes + ':' + seconds; |
|
|
|
|
} |
|
|
|
@ -14,15 +19,13 @@ function stylePlayer(player, video) {
@@ -14,15 +19,13 @@ function stylePlayer(player, video) {
|
|
|
|
|
let skin = attachSkin(video.dataset.ckin); |
|
|
|
|
player.classList.add(skin); |
|
|
|
|
|
|
|
|
|
let overlay = video.dataset.overlay; |
|
|
|
|
addOverlay(player, overlay); |
|
|
|
|
|
|
|
|
|
let html = buildControls(skin); |
|
|
|
|
player.insertAdjacentHTML('beforeend', html); |
|
|
|
|
let updateInterval = 0; |
|
|
|
|
let elapsed = 0; |
|
|
|
|
let prevTime = 0; |
|
|
|
|
|
|
|
|
|
var stopAndScrubTimeout = 0; |
|
|
|
|
|
|
|
|
|
if(skin === 'default') { |
|
|
|
|
if (skin === 'default') { |
|
|
|
|
var progress = player.querySelector('.progress');; |
|
|
|
|
var progressBar = player.querySelector('.progress__filled'); |
|
|
|
|
var toggle = player.querySelectorAll('.toggle'); |
|
|
|
@ -30,7 +33,6 @@ function stylePlayer(player, video) {
@@ -30,7 +33,6 @@ function stylePlayer(player, video) {
|
|
|
|
|
var seek = player.querySelector('#seek'); |
|
|
|
|
var timeElapsed = player.querySelector('#time-elapsed'); |
|
|
|
|
var timeDuration = player.querySelector('#time-duration'); |
|
|
|
|
seek.setAttribute('max', video.duration); |
|
|
|
|
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); |
|
|
|
|
|
|
|
|
|
toggle.forEach((button) => { |
|
|
|
@ -39,34 +41,58 @@ function stylePlayer(player, video) {
@@ -39,34 +41,58 @@ function stylePlayer(player, video) {
|
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
video.addEventListener('click', function() { |
|
|
|
|
video.addEventListener('click', function () { |
|
|
|
|
togglePlay(this, player); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
video.addEventListener('play', function() { |
|
|
|
|
video.addEventListener('play', function () { |
|
|
|
|
updateButton(this, toggle); |
|
|
|
|
updateInterval = setInterval(function () { |
|
|
|
|
if (video.paused) return; //chtob ne prigal seek pri peremotke
|
|
|
|
|
//elapsed += 0.02; // Increase with timer interval
|
|
|
|
|
if (video.currentTime != prevTime) { |
|
|
|
|
elapsed = video.currentTime; // Update if getCurrentTime was changed
|
|
|
|
|
prevTime = video.currentTime; |
|
|
|
|
} |
|
|
|
|
let scaleX = (elapsed / video.duration); |
|
|
|
|
progressBar.style.transform = 'scaleX(' + scaleX + ')'; |
|
|
|
|
if (video.paused) clearInterval(updateInterval); |
|
|
|
|
seek.value = video.currentTime * 1000; |
|
|
|
|
}, 20); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
video.addEventListener('pause', function() { |
|
|
|
|
video.addEventListener('ended', function () { |
|
|
|
|
progressBar.style.transform = 'scaleX(1)'; |
|
|
|
|
seek.value = video.currentTime * 1000; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
video.addEventListener('pause', function () { |
|
|
|
|
updateButton(this, toggle); |
|
|
|
|
clearInterval(updateInterval); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
video.addEventListener('dblclick', function () { |
|
|
|
|
return toggleFullScreen(player, fullScreenButton); |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
let mousedown = false; |
|
|
|
|
let stopAndScrubTimeout = 0; |
|
|
|
|
progress.addEventListener('mousemove', (e) => { |
|
|
|
|
return mousedown && scrub(e, video, progress); |
|
|
|
|
return mousedown && scrub(e, video, progress, progressBar); |
|
|
|
|
}); |
|
|
|
|
progress.addEventListener('mousedown', (e) => { |
|
|
|
|
//console.log(video.currentTime);
|
|
|
|
|
scrub(e, video, progress, progressBar); |
|
|
|
|
scrub(e, video, progress, progressBar, updateInterval); |
|
|
|
|
//Таймер для того, чтобы стопать видео, если зажал мышку и не отпустил клик
|
|
|
|
|
stopAndScrubTimeout = setTimeout(function() { |
|
|
|
|
stopAndScrubTimeout = setTimeout(function () { |
|
|
|
|
togglePlay(video, player, 1); |
|
|
|
|
}, 150); |
|
|
|
|
|
|
|
|
|
return mousedown = true; |
|
|
|
|
}); |
|
|
|
|
progress.addEventListener('mouseup', () => { |
|
|
|
|
if (typeof stopAndScrubTimeout !== 'undefined') { |
|
|
|
|
clearTimeout(stopAndScrubTimeout); |
|
|
|
|
} |
|
|
|
|
togglePlay(video, player, 0); |
|
|
|
|
return mousedown = false; |
|
|
|
|
}); |
|
|
|
@ -78,7 +104,7 @@ function stylePlayer(player, video) {
@@ -78,7 +104,7 @@ function stylePlayer(player, video) {
|
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(skin === 'circle') { |
|
|
|
|
if (skin === 'circle') { |
|
|
|
|
let wrapper = document.createElement('div'); |
|
|
|
|
wrapper.classList.add('circle-time-left'); |
|
|
|
|
video.parentNode.insertBefore(wrapper, video); |
|
|
|
@ -89,7 +115,7 @@ function stylePlayer(player, video) {
@@ -89,7 +115,7 @@ function stylePlayer(player, video) {
|
|
|
|
|
var circumference = 2 * Math.PI * radius; |
|
|
|
|
var timeDuration = player.querySelector('.circle-time'); |
|
|
|
|
var iconVolume = player.querySelector('.iconVolume'); |
|
|
|
|
circle.style.strokeDasharray = `${circumference} ${circumference}`; |
|
|
|
|
circle.style.strokeDasharray = circumference + ' ' + circumference; |
|
|
|
|
circle.style.strokeDashoffset = circumference; |
|
|
|
|
circle.addEventListener('click', () => { |
|
|
|
|
togglePlay(video, player); |
|
|
|
@ -97,6 +123,16 @@ function stylePlayer(player, video) {
@@ -97,6 +123,16 @@ function stylePlayer(player, video) {
|
|
|
|
|
|
|
|
|
|
video.addEventListener('play', () => { |
|
|
|
|
iconVolume.style.display = 'none'; |
|
|
|
|
updateInterval = setInterval(function () { |
|
|
|
|
//elapsed += 0.02; // Increase with timer interval
|
|
|
|
|
if (video.currentTime != prevTime) { |
|
|
|
|
elapsed = video.currentTime; // Update if getCurrentTime was changed
|
|
|
|
|
prevTime = video.currentTime; |
|
|
|
|
} |
|
|
|
|
let offset = circumference - elapsed / video.duration * circumference; |
|
|
|
|
circle.style.strokeDashoffset = offset; |
|
|
|
|
if (video.paused) clearInterval(updateInterval); |
|
|
|
|
}, 20); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
video.addEventListener('pause', () => { |
|
|
|
@ -105,16 +141,16 @@ function stylePlayer(player, video) {
@@ -105,16 +141,16 @@ function stylePlayer(player, video) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//Для хрома
|
|
|
|
|
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); |
|
|
|
|
if(skin === 'default') seek.setAttribute('max', video.duration); |
|
|
|
|
timeDuration.innerHTML = String(Math.round(video.duration)).toHHMMSS(); |
|
|
|
|
if (skin === 'default') seek.setAttribute('max', video.duration * 1000); |
|
|
|
|
//Для Opera / Safari / IE
|
|
|
|
|
video.addEventListener('loadeddata', function() { |
|
|
|
|
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); |
|
|
|
|
if(skin === 'default') seek.setAttribute('max', video.duration); |
|
|
|
|
video.addEventListener('loadeddata', function () { |
|
|
|
|
timeDuration.innerHTML = String(Math.round(video.duration)).toHHMMSS(); |
|
|
|
|
if (skin === 'default') seek.setAttribute('max', video.duration * 1000); |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
video.addEventListener('timeupdate', function() { |
|
|
|
|
handleProgress(this, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed); |
|
|
|
|
video.addEventListener('timeupdate', function () { |
|
|
|
|
updateInterval = handleProgress(this, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed, updateInterval); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -123,11 +159,11 @@ function showControls(video) {
@@ -123,11 +159,11 @@ function showControls(video) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function togglePlay(video, player, stop) { |
|
|
|
|
if(stop == 1) { |
|
|
|
|
if (stop == 1) { |
|
|
|
|
video['pause'](); |
|
|
|
|
player.classList.remove('is-playing'); |
|
|
|
|
return; |
|
|
|
|
} else if(stop == 0) { |
|
|
|
|
} else if (stop == 0) { |
|
|
|
|
video['play'](); |
|
|
|
|
player.classList.add('is-playing'); |
|
|
|
|
return; |
|
|
|
@ -146,23 +182,48 @@ function updateButton(video, toggle) {
@@ -146,23 +182,48 @@ function updateButton(video, toggle) {
|
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function handleProgress(video, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed) { |
|
|
|
|
let percent = video.currentTime / video.duration * 100; |
|
|
|
|
if(skin === 'default') { |
|
|
|
|
progressBar.style.width = percent + '%'; |
|
|
|
|
seek.value = video.currentTime; |
|
|
|
|
function handleProgress(video, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed, updateInterval, mousemove) { |
|
|
|
|
clearInterval(updateInterval); |
|
|
|
|
let elapsed = 0; |
|
|
|
|
let prevTime = 0; |
|
|
|
|
if (skin === 'default') { |
|
|
|
|
updateInterval = setInterval(function () { |
|
|
|
|
if (video.paused) return; |
|
|
|
|
if (video.currentTime != prevTime) { |
|
|
|
|
elapsed = video.currentTime; // Update if getCurrentTime was changed
|
|
|
|
|
prevTime = video.currentTime; |
|
|
|
|
} |
|
|
|
|
let scaleX = (elapsed / video.duration); |
|
|
|
|
progressBar.style.transform = 'scaleX(' + scaleX + ')'; |
|
|
|
|
if (video.paused) clearInterval(updateInterval); |
|
|
|
|
seek.value = video.currentTime * 1000; |
|
|
|
|
}, 20); |
|
|
|
|
timeElapsed.innerHTML = String(video.currentTime | 0).toHHMMSS(); |
|
|
|
|
} else if(skin === 'circle') { |
|
|
|
|
let timeLeft = String((video.duration - video.currentTime) | 0).toHHMMSS(); |
|
|
|
|
let offset = circumference - percent / 100 * circumference; |
|
|
|
|
return updateInterval; |
|
|
|
|
} else if (skin === 'circle') { |
|
|
|
|
updateInterval = setInterval(function () { |
|
|
|
|
if (video.currentTime != prevTime) { |
|
|
|
|
elapsed = video.currentTime; // Update if getCurrentTime was changed
|
|
|
|
|
prevTime = video.currentTime; |
|
|
|
|
} |
|
|
|
|
let offset = circumference - elapsed / video.duration * circumference; |
|
|
|
|
circle.style.strokeDashoffset = offset; |
|
|
|
|
if(timeLeft != 0 | 0) timeDuration.innerHTML = timeLeft; |
|
|
|
|
if (video.paused) clearInterval(updateInterval); |
|
|
|
|
}, 20); |
|
|
|
|
let timeLeft = String((video.duration - video.currentTime) | 0).toHHMMSS(); |
|
|
|
|
if (timeLeft != 0 | 0) timeDuration.innerHTML = timeLeft; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function scrub(e, video, progress) { |
|
|
|
|
function scrub(e, video, progress, progressBar) { |
|
|
|
|
let scrubTime = e.offsetX / progress.offsetWidth * video.duration; |
|
|
|
|
video.currentTime = scrubTime; |
|
|
|
|
let scaleX = scrubTime / video.duration; |
|
|
|
|
|
|
|
|
|
if (scaleX > 1) scaleX = 1; |
|
|
|
|
if (scaleX < 0) scaleX = 0; |
|
|
|
|
|
|
|
|
|
progressBar.style.transform = 'scaleX(' + scaleX + ')'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export function wrapPlayer(video) { |
|
|
|
@ -179,8 +240,9 @@ export function wrapPlayer(video) {
@@ -179,8 +240,9 @@ export function wrapPlayer(video) {
|
|
|
|
|
|
|
|
|
|
function buildControls(skin) { |
|
|
|
|
let html = []; |
|
|
|
|
if(skin === 'default') { |
|
|
|
|
if (skin === 'default') { |
|
|
|
|
html.push('<button class="' + skin + '__button--big toggle tgico-largeplay" title="Toggle Play"></button>'); |
|
|
|
|
html.push('<div class="' + skin + '__gradient-bottom ckin__controls"></div>'); |
|
|
|
|
html.push('<div class="' + skin + '__controls ckin__controls">'); |
|
|
|
|
html.push('<div class="progress">', |
|
|
|
|
'<div class="progress__filled"></div><input class="seek" id="seek" value="0" min="0" type="range" step="0.1" max="0">', |
|
|
|
@ -195,9 +257,9 @@ function buildControls(skin) {
@@ -195,9 +257,9 @@ function buildControls(skin) {
|
|
|
|
|
'</div>', |
|
|
|
|
'<div class="right-controls"><button class="' + skin + '__button fullscreen tgico-fullscreen" title="Full Screen"></button></div></div>'); |
|
|
|
|
html.push('</div>'); |
|
|
|
|
} else if(skin === 'circle') { |
|
|
|
|
} else if (skin === 'circle') { |
|
|
|
|
html.push('<svg class="progress-ring" width="200px" height="200px">', |
|
|
|
|
'<circle class="progress-ring__circle" stroke="white" stroke-opacity="0.3" stroke-width="3.5" cx="100" cy="100" r="93" fill="transparent"/>', |
|
|
|
|
'<circle class="progress-ring__circle" stroke="white" stroke-opacity="0.3" stroke-width="3.5" cx="100" cy="100" r="93" fill="transparent" transform="rotate(-90, 100, 100)"/>', |
|
|
|
|
'</svg>'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -206,33 +268,25 @@ function buildControls(skin) {
@@ -206,33 +268,25 @@ function buildControls(skin) {
|
|
|
|
|
|
|
|
|
|
function attachSkin(skin) { |
|
|
|
|
console.log("skin: " + skin); |
|
|
|
|
if(typeof skin != 'undefined' && skin != '') { |
|
|
|
|
if (typeof skin != 'undefined' && skin != '') { |
|
|
|
|
return skin; |
|
|
|
|
} else { |
|
|
|
|
return 'default'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function addOverlay(player, overlay) { |
|
|
|
|
if(overlay == 1) { |
|
|
|
|
player.classList.add('ckin__overlay'); |
|
|
|
|
} else { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function toggleFullScreen(player, fullScreenButton) { |
|
|
|
|
// alternative standard method
|
|
|
|
|
if(!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { |
|
|
|
|
if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { |
|
|
|
|
player.classList.add('ckin__fullscreen'); |
|
|
|
|
|
|
|
|
|
if(player.requestFullscreen) { |
|
|
|
|
if (player.requestFullscreen) { |
|
|
|
|
player.requestFullscreen(); |
|
|
|
|
} else if(player.mozRequestFullScreen) { |
|
|
|
|
} else if (player.mozRequestFullScreen) { |
|
|
|
|
player.mozRequestFullScreen(); // Firefox
|
|
|
|
|
} else if(player.webkitRequestFullscreen) { |
|
|
|
|
} else if (player.webkitRequestFullscreen) { |
|
|
|
|
player.webkitRequestFullscreen(); // Chrome and Safari
|
|
|
|
|
} else if(player.msRequestFullscreen) { |
|
|
|
|
} else if (player.msRequestFullscreen) { |
|
|
|
|
player.msRequestFullscreen(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -242,13 +296,13 @@ function toggleFullScreen(player, fullScreenButton) {
@@ -242,13 +296,13 @@ function toggleFullScreen(player, fullScreenButton) {
|
|
|
|
|
} else { |
|
|
|
|
player.classList.remove('ckin__fullscreen'); |
|
|
|
|
|
|
|
|
|
if(document.cancelFullScreen) { |
|
|
|
|
if (document.cancelFullScreen) { |
|
|
|
|
document.cancelFullScreen(); |
|
|
|
|
} else if(document.mozCancelFullScreen) { |
|
|
|
|
} else if (document.mozCancelFullScreen) { |
|
|
|
|
document.mozCancelFullScreen(); |
|
|
|
|
} else if(document.webkitCancelFullScreen) { |
|
|
|
|
} else if (document.webkitCancelFullScreen) { |
|
|
|
|
document.webkitCancelFullScreen(); |
|
|
|
|
} else if(document.msExitFullscreen) { |
|
|
|
|
} else if (document.msExitFullscreen) { |
|
|
|
|
document.msExitFullscreen(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -260,15 +314,9 @@ function toggleFullScreen(player, fullScreenButton) {
@@ -260,15 +314,9 @@ function toggleFullScreen(player, fullScreenButton) {
|
|
|
|
|
|
|
|
|
|
function onFullScreen(e, player) { |
|
|
|
|
let isFullscreenNow = document.webkitFullscreenElement !== null; |
|
|
|
|
if(!isFullscreenNow) { |
|
|
|
|
if (!isFullscreenNow) { |
|
|
|
|
player.classList.remove('ckin__fullscreen'); |
|
|
|
|
|
|
|
|
|
/* let el = player.querySelector('.fullscreen'); |
|
|
|
|
el.classList.remove('tgico-smallscreen'); |
|
|
|
|
el.classList.add('tgico-fullscreen'); */ |
|
|
|
|
} else { |
|
|
|
|
// player.querySelector('.fullscreen').innerHTML = iconExpand;
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|