audiomessages & new player
This commit is contained in:
parent
2a3a5cdd2f
commit
956a260a27
@ -29,7 +29,8 @@ export type MTDocument = {
|
||||
h?: number,
|
||||
w?: number,
|
||||
file_name?: string,
|
||||
file?: File
|
||||
file?: File,
|
||||
duration?: number
|
||||
};
|
||||
|
||||
export type MTPhotoSize = {
|
||||
@ -235,24 +236,56 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement
|
||||
return docDiv;
|
||||
}
|
||||
|
||||
let lastAudioToggle: HTMLDivElement = null;
|
||||
|
||||
export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
let div = document.createElement('div');
|
||||
div.classList.add('audio');
|
||||
|
||||
let duration = doc.duration;
|
||||
|
||||
// @ts-ignore
|
||||
let durationStr = String(duration | 0).toHHMMSS(true);
|
||||
|
||||
div.innerHTML = `
|
||||
<div class="audio-toggle audio-ico tgico-largeplay"></div>
|
||||
<div class="audio-download"><div class="tgico-download"></div></div>
|
||||
<div class="audio-title"></div>
|
||||
<div class="audio-subtitle"></div>
|
||||
<div class="audio-time"></div>
|
||||
<div class="audio-time">${durationStr}</div>
|
||||
`;
|
||||
|
||||
console.log('wrapping audio', doc);
|
||||
console.log('wrapping audio', doc, doc.attributes[0].waveform);
|
||||
|
||||
let timeDiv = div.lastElementChild as HTMLDivElement;
|
||||
|
||||
let downloadDiv = div.querySelector('.audio-download') as HTMLDivElement;
|
||||
let preloader: ProgressivePreloader;
|
||||
let promise: CancellablePromise<Blob>;
|
||||
|
||||
let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
svg.classList.add('audio-waveform');
|
||||
svg.setAttributeNS(null, 'width', '250');
|
||||
svg.setAttributeNS(null, 'height', '23');
|
||||
svg.setAttributeNS(null, 'viewBox', '0 0 250 23');
|
||||
|
||||
div.insertBefore(svg, div.lastElementChild);
|
||||
let wave = doc.attributes[0].waveform as Uint8Array;
|
||||
|
||||
let index = 0;
|
||||
for(let uint8 of wave) {
|
||||
let percents = uint8 / 255;
|
||||
|
||||
let height = 23 * percents;
|
||||
if(/* !height || */height < 2) {
|
||||
height = 2;
|
||||
}
|
||||
|
||||
svg.insertAdjacentHTML('beforeend', `
|
||||
<rect x="${index * 4}" y="${23 - height}" width="2" height="${height}" rx="1" ry="1"></rect>
|
||||
`);
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
let onClick = () => {
|
||||
if(!promise) {
|
||||
if(downloadDiv.classList.contains('downloading')) {
|
||||
@ -276,9 +309,57 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
source.type = doc.mime_type;
|
||||
|
||||
div.removeEventListener('click', onClick);
|
||||
div.querySelector('.audio-toggle').addEventListener('click', () => {
|
||||
audio.currentTime = 0;
|
||||
audio.play();
|
||||
let toggle = div.querySelector('.audio-toggle') as HTMLDivElement;
|
||||
|
||||
let interval = 0;
|
||||
|
||||
toggle.addEventListener('click', () => {
|
||||
if(audio.paused) {
|
||||
if(lastAudioToggle && lastAudioToggle.classList.contains('tgico-largepause')) {
|
||||
lastAudioToggle.click();
|
||||
}
|
||||
|
||||
audio.currentTime = 0;
|
||||
audio.play();
|
||||
|
||||
lastAudioToggle = toggle;
|
||||
|
||||
toggle.classList.remove('tgico-largeplay');
|
||||
toggle.classList.add('tgico-largepause');
|
||||
|
||||
(Array.from(svg.children) as HTMLElement[]).forEach(node => node.classList.remove('active'));
|
||||
|
||||
let lastIndex = 0;
|
||||
interval = setInterval(() => {
|
||||
if(lastIndex >= svg.childElementCount) {
|
||||
clearInterval(interval);
|
||||
return;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true);
|
||||
|
||||
//svg.children[lastIndex].setAttributeNS(null, 'fill', '#000');
|
||||
svg.children[lastIndex].classList.add('active');
|
||||
++lastIndex;
|
||||
//console.log('lastIndex:', lastIndex, audio.currentTime);
|
||||
}, duration * 1000 / svg.childElementCount | 0/* 63 * duration / 10 */);
|
||||
} else {
|
||||
audio.pause();
|
||||
toggle.classList.add('tgico-largeplay');
|
||||
toggle.classList.remove('tgico-largepause');
|
||||
|
||||
clearInterval(interval);
|
||||
}
|
||||
});
|
||||
|
||||
audio.addEventListener('ended', () => {
|
||||
toggle.classList.add('tgico-largeplay');
|
||||
toggle.classList.remove('tgico-largepause');
|
||||
clearInterval(interval);
|
||||
|
||||
// @ts-ignore
|
||||
timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true);
|
||||
});
|
||||
|
||||
audio.append(source);
|
||||
|
@ -112,7 +112,7 @@ class AppSidebarRight {
|
||||
|
||||
this.prevTabID = id;
|
||||
|
||||
this.log('setVirtualContainer', id, this.sharedMediaSelected);
|
||||
//this.log('setVirtualContainer', id, this.sharedMediaSelected);
|
||||
this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected);
|
||||
|
||||
if(this.savedVirtualStates[id]) {
|
||||
@ -169,7 +169,7 @@ class AppSidebarRight {
|
||||
let media = Array.from(this.sharedMediaSelected.childNodes).slice(-15);
|
||||
for(let div of media) {
|
||||
if(isElementInViewport(div)) {
|
||||
this.log('Will load more media');
|
||||
//this.log('Will load more media');
|
||||
this.loadSidebarMedia(true);
|
||||
|
||||
break;
|
||||
@ -256,12 +256,12 @@ class AppSidebarRight {
|
||||
let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
|
||||
|
||||
if(!media) {
|
||||
this.log('no media!', message);
|
||||
//this.log('no media!', message);
|
||||
break;
|
||||
}
|
||||
|
||||
if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) {
|
||||
this.log('broken video', media);
|
||||
//this.log('broken video', media);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -334,7 +334,7 @@ class AppSidebarRight {
|
||||
let previewDiv = document.createElement('div');
|
||||
previewDiv.classList.add('preview');
|
||||
|
||||
this.log('wrapping webpage', webpage);
|
||||
//this.log('wrapping webpage', webpage);
|
||||
|
||||
if(webpage.photo) {
|
||||
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 380, 0))
|
||||
@ -394,7 +394,7 @@ class AppSidebarRight {
|
||||
} */
|
||||
|
||||
default:
|
||||
console.warn('death is my friend', message);
|
||||
//console.warn('death is my friend', message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -416,7 +416,7 @@ class AppSidebarRight {
|
||||
this.loadSidebarMediaPromises = {};
|
||||
this.lastSharedMediaDiv = document.createElement('div');
|
||||
|
||||
this.log('fillProfileElements');
|
||||
//this.log('fillProfileElements');
|
||||
|
||||
this.savedVirtualStates = {};
|
||||
this.prevTabID = -1;
|
||||
@ -483,7 +483,7 @@ class AppSidebarRight {
|
||||
setText(userFull.rAbout, this.profileElements.bio);
|
||||
}
|
||||
|
||||
this.log('userFull', userFull);
|
||||
//this.log('userFull', userFull);
|
||||
|
||||
if(userFull.pinned_msg_id) { // request pinned message
|
||||
appImManager.pinnedMsgID = userFull.pinned_msg_id;
|
||||
@ -499,7 +499,7 @@ class AppSidebarRight {
|
||||
return;
|
||||
}
|
||||
|
||||
this.log('chatInfo res 2:', chatFull);
|
||||
//this.log('chatInfo res 2:', chatFull);
|
||||
|
||||
if(chatFull.about) {
|
||||
setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio);
|
||||
|
510
src/lib/ckin.js
510
src/lib/ckin.js
@ -1,280 +1,328 @@
|
||||
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;
|
||||
}
|
||||
|
||||
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 skin = attachSkin(video.dataset.ckin);
|
||||
player.classList.add(skin);
|
||||
|
||||
var stopAndScrubTimeout = 0;
|
||||
|
||||
if(skin === 'default') {
|
||||
var progress = player.querySelector('.progress');;
|
||||
var progressBar = player.querySelector('.progress__filled');
|
||||
var toggle = player.querySelectorAll('.toggle');
|
||||
var fullScreenButton = player.querySelector('.fullscreen');
|
||||
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) => {
|
||||
return button.addEventListener('click', () => {
|
||||
togglePlay(video, player);
|
||||
});
|
||||
});
|
||||
|
||||
video.addEventListener('click', function() {
|
||||
togglePlay(this, player);
|
||||
});
|
||||
|
||||
video.addEventListener('play', function() {
|
||||
updateButton(this, toggle);
|
||||
});
|
||||
|
||||
video.addEventListener('pause', function() {
|
||||
updateButton(this, toggle);
|
||||
});
|
||||
|
||||
let mousedown = false;
|
||||
progress.addEventListener('mousemove', (e) => {
|
||||
return mousedown && scrub(e, video, progress);
|
||||
});
|
||||
progress.addEventListener('mousedown', (e) => {
|
||||
//console.log(video.currentTime);
|
||||
scrub(e, video, progress, progressBar);
|
||||
//Таймер для того, чтобы стопать видео, если зажал мышку и не отпустил клик
|
||||
stopAndScrubTimeout = setTimeout(function() {
|
||||
togglePlay(video, player, 1);
|
||||
}, 150);
|
||||
|
||||
return mousedown = true;
|
||||
});
|
||||
progress.addEventListener('mouseup', () => {
|
||||
clearTimeout(stopAndScrubTimeout);
|
||||
togglePlay(video, player, 0);
|
||||
return mousedown = false;
|
||||
});
|
||||
fullScreenButton.addEventListener('click', (e) => {
|
||||
return toggleFullScreen(player, fullScreenButton);
|
||||
});
|
||||
addListenerMulti(player, 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', (e) => {
|
||||
return onFullScreen(e, player);
|
||||
});
|
||||
}
|
||||
|
||||
if(skin === 'circle') {
|
||||
let wrapper = document.createElement('div');
|
||||
wrapper.classList.add('circle-time-left');
|
||||
video.parentNode.insertBefore(wrapper, video);
|
||||
wrapper.innerHTML = '<div class="circle-time"></div><div class="iconVolume tgico-nosound"></div>';
|
||||
|
||||
var circle = player.querySelector('.progress-ring__circle');
|
||||
var radius = circle.r.baseVal.value;
|
||||
var circumference = 2 * Math.PI * radius;
|
||||
var timeDuration = player.querySelector('.circle-time');
|
||||
var iconVolume = player.querySelector('.iconVolume');
|
||||
circle.style.strokeDasharray = `${circumference} ${circumference}`;
|
||||
circle.style.strokeDashoffset = circumference;
|
||||
circle.addEventListener('click', () => {
|
||||
togglePlay(video, player);
|
||||
});
|
||||
|
||||
video.addEventListener('play', () => {
|
||||
iconVolume.style.display = 'none';
|
||||
});
|
||||
|
||||
video.addEventListener('pause', () => {
|
||||
iconVolume.style.display = '';
|
||||
});
|
||||
}
|
||||
let html = buildControls(skin);
|
||||
player.insertAdjacentHTML('beforeend', html);
|
||||
let updateInterval = 0;
|
||||
let elapsed = 0;
|
||||
let prevTime = 0;
|
||||
|
||||
//Для хрома
|
||||
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS();
|
||||
if(skin === 'default') seek.setAttribute('max', video.duration);
|
||||
//Для Opera / Safari / IE
|
||||
video.addEventListener('loadeddata', function() {
|
||||
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS();
|
||||
if(skin === 'default') seek.setAttribute('max', video.duration);
|
||||
})
|
||||
|
||||
video.addEventListener('timeupdate', function() {
|
||||
handleProgress(this, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed);
|
||||
});
|
||||
if (skin === 'default') {
|
||||
var progress = player.querySelector('.progress');;
|
||||
var progressBar = player.querySelector('.progress__filled');
|
||||
var toggle = player.querySelectorAll('.toggle');
|
||||
var fullScreenButton = player.querySelector('.fullscreen');
|
||||
var seek = player.querySelector('#seek');
|
||||
var timeElapsed = player.querySelector('#time-elapsed');
|
||||
var timeDuration = player.querySelector('#time-duration');
|
||||
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS();
|
||||
|
||||
toggle.forEach((button) => {
|
||||
return button.addEventListener('click', () => {
|
||||
togglePlay(video, player);
|
||||
});
|
||||
});
|
||||
|
||||
video.addEventListener('click', function () {
|
||||
togglePlay(this, player);
|
||||
});
|
||||
|
||||
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('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, progressBar);
|
||||
});
|
||||
progress.addEventListener('mousedown', (e) => {
|
||||
scrub(e, video, progress, progressBar, updateInterval);
|
||||
//Таймер для того, чтобы стопать видео, если зажал мышку и не отпустил клик
|
||||
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;
|
||||
});
|
||||
fullScreenButton.addEventListener('click', (e) => {
|
||||
return toggleFullScreen(player, fullScreenButton);
|
||||
});
|
||||
addListenerMulti(player, 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', (e) => {
|
||||
return onFullScreen(e, player);
|
||||
});
|
||||
}
|
||||
|
||||
if (skin === 'circle') {
|
||||
let wrapper = document.createElement('div');
|
||||
wrapper.classList.add('circle-time-left');
|
||||
video.parentNode.insertBefore(wrapper, video);
|
||||
wrapper.innerHTML = '<div class="circle-time"></div><div class="iconVolume tgico-nosound"></div>';
|
||||
|
||||
var circle = player.querySelector('.progress-ring__circle');
|
||||
var radius = circle.r.baseVal.value;
|
||||
var circumference = 2 * Math.PI * radius;
|
||||
var timeDuration = player.querySelector('.circle-time');
|
||||
var iconVolume = player.querySelector('.iconVolume');
|
||||
circle.style.strokeDasharray = circumference + ' ' + circumference;
|
||||
circle.style.strokeDashoffset = circumference;
|
||||
circle.addEventListener('click', () => {
|
||||
togglePlay(video, player);
|
||||
});
|
||||
|
||||
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', () => {
|
||||
iconVolume.style.display = '';
|
||||
});
|
||||
}
|
||||
|
||||
//Для хрома
|
||||
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(Math.round(video.duration)).toHHMMSS();
|
||||
if (skin === 'default') seek.setAttribute('max', video.duration * 1000);
|
||||
})
|
||||
|
||||
video.addEventListener('timeupdate', function () {
|
||||
updateInterval = handleProgress(this, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed, updateInterval);
|
||||
});
|
||||
}
|
||||
|
||||
function showControls(video) {
|
||||
video.setAttribute("controls", "controls");
|
||||
video.setAttribute("controls", "controls");
|
||||
}
|
||||
|
||||
function togglePlay(video, player, stop) {
|
||||
if(stop == 1) {
|
||||
video['pause']();
|
||||
player.classList.remove('is-playing');
|
||||
return;
|
||||
} else if(stop == 0) {
|
||||
video['play']();
|
||||
player.classList.add('is-playing');
|
||||
return;
|
||||
}
|
||||
|
||||
let method = video.paused ? 'play' : 'pause';
|
||||
video[method]();
|
||||
video.paused ? player.classList.remove('is-playing') : player.classList.add('is-playing');
|
||||
if (stop == 1) {
|
||||
video['pause']();
|
||||
player.classList.remove('is-playing');
|
||||
return;
|
||||
} else if (stop == 0) {
|
||||
video['play']();
|
||||
player.classList.add('is-playing');
|
||||
return;
|
||||
}
|
||||
|
||||
let method = video.paused ? 'play' : 'pause';
|
||||
video[method]();
|
||||
video.paused ? player.classList.remove('is-playing') : player.classList.add('is-playing');
|
||||
}
|
||||
|
||||
function updateButton(video, toggle) {
|
||||
let icon = video.paused ? 'tgico-play' : 'tgico-pause';
|
||||
toggle.forEach((button) => {
|
||||
button.classList.remove('tgico-play', 'tgico-pause');
|
||||
button.classList.add(icon);
|
||||
});
|
||||
let icon = video.paused ? 'tgico-play' : 'tgico-pause';
|
||||
toggle.forEach((button) => {
|
||||
button.classList.remove('tgico-play', 'tgico-pause');
|
||||
button.classList.add(icon);
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
circle.style.strokeDashoffset = offset;
|
||||
if(timeLeft != 0 | 0) timeDuration.innerHTML = timeLeft;
|
||||
}
|
||||
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();
|
||||
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 (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) {
|
||||
let scrubTime = e.offsetX / progress.offsetWidth * video.duration;
|
||||
video.currentTime = scrubTime;
|
||||
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) {
|
||||
let wrapper = document.createElement('div');
|
||||
wrapper.classList.add('ckin__player');
|
||||
|
||||
video.parentNode.insertBefore(wrapper, video);
|
||||
wrapper.appendChild(video);
|
||||
let wrapper = document.createElement('div');
|
||||
wrapper.classList.add('ckin__player');
|
||||
|
||||
stylePlayer(wrapper, video);
|
||||
video.parentNode.insertBefore(wrapper, video);
|
||||
wrapper.appendChild(video);
|
||||
|
||||
return wrapper;
|
||||
stylePlayer(wrapper, video);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function buildControls(skin) {
|
||||
let html = [];
|
||||
if(skin === 'default') {
|
||||
html.push('<button class="' + skin + '__button--big toggle tgico-largeplay" title="Toggle Play"></button>');
|
||||
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">',
|
||||
'</div>',
|
||||
'<div class="bottom-controls">',
|
||||
'<div class="left-controls"><button class="' + skin + '__button toggle tgico-play" title="Toggle Video"></button>',
|
||||
'<div class="time">',
|
||||
'<time id="time-elapsed">0:00</time>',
|
||||
'<span> / </span>',
|
||||
'<time id="time-duration">0:00</time>',
|
||||
'</div>',
|
||||
'</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') {
|
||||
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"/>',
|
||||
'</svg>');
|
||||
}
|
||||
|
||||
return html.join('');
|
||||
let html = [];
|
||||
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">',
|
||||
'</div>',
|
||||
'<div class="bottom-controls">',
|
||||
'<div class="left-controls"><button class="' + skin + '__button toggle tgico-play" title="Toggle Video"></button>',
|
||||
'<div class="time">',
|
||||
'<time id="time-elapsed">0:00</time>',
|
||||
'<span> / </span>',
|
||||
'<time id="time-duration">0:00</time>',
|
||||
'</div>',
|
||||
'</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') {
|
||||
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" transform="rotate(-90, 100, 100)"/>',
|
||||
'</svg>');
|
||||
}
|
||||
|
||||
return html.join('');
|
||||
}
|
||||
|
||||
function attachSkin(skin) {
|
||||
console.log("skin: " + 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;
|
||||
}
|
||||
console.log("skin: " + skin);
|
||||
if (typeof skin != 'undefined' && skin != '') {
|
||||
return skin;
|
||||
} else {
|
||||
return 'default';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFullScreen(player, fullScreenButton) {
|
||||
// alternative standard method
|
||||
if(!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
|
||||
player.classList.add('ckin__fullscreen');
|
||||
|
||||
if(player.requestFullscreen) {
|
||||
player.requestFullscreen();
|
||||
} else if(player.mozRequestFullScreen) {
|
||||
player.mozRequestFullScreen(); // Firefox
|
||||
} else if(player.webkitRequestFullscreen) {
|
||||
player.webkitRequestFullscreen(); // Chrome and Safari
|
||||
} else if(player.msRequestFullscreen) {
|
||||
player.msRequestFullscreen();
|
||||
}
|
||||
// alternative standard method
|
||||
if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
|
||||
player.classList.add('ckin__fullscreen');
|
||||
|
||||
fullScreenButton.classList.remove('tgico-fullscreen');
|
||||
fullScreenButton.classList.add('tgico-smallscreen');
|
||||
fullScreenButton.setAttribute('title', 'Exit Full Screen');
|
||||
} else {
|
||||
player.classList.remove('ckin__fullscreen');
|
||||
|
||||
if(document.cancelFullScreen) {
|
||||
document.cancelFullScreen();
|
||||
} else if(document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
} else if(document.webkitCancelFullScreen) {
|
||||
document.webkitCancelFullScreen();
|
||||
} else if(document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
if (player.requestFullscreen) {
|
||||
player.requestFullscreen();
|
||||
} else if (player.mozRequestFullScreen) {
|
||||
player.mozRequestFullScreen(); // Firefox
|
||||
} else if (player.webkitRequestFullscreen) {
|
||||
player.webkitRequestFullscreen(); // Chrome and Safari
|
||||
} else if (player.msRequestFullscreen) {
|
||||
player.msRequestFullscreen();
|
||||
}
|
||||
|
||||
fullScreenButton.classList.remove('tgico-smallscreen');
|
||||
fullScreenButton.classList.add('tgico-fullscreen');
|
||||
fullScreenButton.setAttribute('title', 'Full Screen');
|
||||
}
|
||||
fullScreenButton.classList.remove('tgico-fullscreen');
|
||||
fullScreenButton.classList.add('tgico-smallscreen');
|
||||
fullScreenButton.setAttribute('title', 'Exit Full Screen');
|
||||
} else {
|
||||
player.classList.remove('ckin__fullscreen');
|
||||
|
||||
if (document.cancelFullScreen) {
|
||||
document.cancelFullScreen();
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
} else if (document.webkitCancelFullScreen) {
|
||||
document.webkitCancelFullScreen();
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
|
||||
fullScreenButton.classList.remove('tgico-smallscreen');
|
||||
fullScreenButton.classList.add('tgico-fullscreen');
|
||||
fullScreenButton.setAttribute('title', 'Full Screen');
|
||||
}
|
||||
}
|
||||
|
||||
function onFullScreen(e, player) {
|
||||
let isFullscreenNow = document.webkitFullscreenElement !== null;
|
||||
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;
|
||||
|
||||
}
|
||||
let isFullscreenNow = document.webkitFullscreenElement !== null;
|
||||
if (!isFullscreenNow) {
|
||||
player.classList.remove('ckin__fullscreen');
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function addListenerMulti(element, eventNames, listener) {
|
||||
let events = eventNames.split(' ');
|
||||
for (let i = 0, iLen = events.length; i < iLen; i++) {
|
||||
element.addEventListener(events[i], listener, false);
|
||||
}
|
||||
let events = eventNames.split(' ');
|
||||
for (let i = 0, iLen = events.length; i < iLen; i++) {
|
||||
element.addEventListener(events[i], listener, false);
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +239,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.hide-name) {
|
||||
.audio {
|
||||
margin: 4px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.forward {
|
||||
opacity: 1;
|
||||
@ -897,6 +903,26 @@
|
||||
left: auto;
|
||||
right: -2.5rem;
|
||||
}
|
||||
|
||||
.audio {
|
||||
&-waveform {
|
||||
rect {
|
||||
fill: #B8DDA9;
|
||||
|
||||
&.active {
|
||||
fill: #68AB5A;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-time {
|
||||
color: #68AB5A;
|
||||
}
|
||||
|
||||
&-toggle, &-download {
|
||||
background-color: #68AB5A;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,3 @@
|
||||
/*!
|
||||
ckin v0.0.1: Custom HTML5 Video Player Skins.
|
||||
(c) 2017
|
||||
MIT License
|
||||
git+https://github.com/hunzaboy/ckin.git
|
||||
*/
|
||||
|
||||
/* video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
cursor: pointer;
|
||||
} */
|
||||
|
||||
.ckin {
|
||||
&__player {
|
||||
letter-spacing: 0.02em;
|
||||
@ -65,7 +52,6 @@
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
//border-radius: 5px;
|
||||
transition: opacity .2s;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
@ -87,7 +73,6 @@
|
||||
color: #fff;
|
||||
outline: 0;
|
||||
padding: 3px 10px 6px 10px;
|
||||
/* padding: 6px 10px 6px 10px; */
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
@ -134,16 +119,40 @@
|
||||
right: 0;
|
||||
left: 0;
|
||||
transition: all .3s;
|
||||
/* background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, transparent 100%); */
|
||||
/* font-size: 32px; */
|
||||
text-align: left;
|
||||
direction: ltr;
|
||||
/* padding-top: 7px; */
|
||||
border-radius: 0 0 5px 5px;
|
||||
z-index: 3;
|
||||
z-index: 6;
|
||||
}
|
||||
}
|
||||
|
||||
.default__gradient-bottom {
|
||||
height: 49px;
|
||||
// padding-top: 49px;
|
||||
padding-top: 93px;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background-position: bottom;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
background-repeat: repeat-x;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);
|
||||
-moz-transition: all .3s;
|
||||
-webkit-transition: all .3s;
|
||||
transition: all .3s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.default.is-playing .default__gradient-bottom {
|
||||
-ms-transform: translateY(50px);
|
||||
transform: translateY(50px);
|
||||
}
|
||||
|
||||
.default.is-playing:hover .default__gradient-bottom {
|
||||
-ms-transform: translateY(0px);
|
||||
transform: translateY(0px);
|
||||
}
|
||||
|
||||
.default.is-playing:before {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
@ -168,9 +177,7 @@
|
||||
|
||||
.default .progress {
|
||||
position: relative;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
margin: 0 8px;
|
||||
margin: 0 16px;
|
||||
height: 5px;
|
||||
transition: height 0.3s;
|
||||
background: rgba(255, 255, 255, 0.38);
|
||||
@ -180,13 +187,11 @@
|
||||
}
|
||||
|
||||
.default .progress__filled {
|
||||
width: 0%;
|
||||
background: #63a2e3;
|
||||
/* -ms-flex: 0;
|
||||
flex: 0;
|
||||
-ms-flex-preferred-size: 0%;
|
||||
flex-basis: 0%; */
|
||||
transform-origin: left;
|
||||
border-radius: 4px;
|
||||
height: 5px;
|
||||
transform: scaleX(0);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
@ -205,6 +210,8 @@ video::-webkit-media-controls-enclosure {
|
||||
background: transparent;
|
||||
height: 4.5px;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.progress input[type=range]:focus {
|
||||
@ -233,22 +240,6 @@ video::-webkit-media-controls-enclosure {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.progress input[type=range].volume {
|
||||
height: 5px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.progress input[type=range].volume::-webkit-slider-runnable-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.progress input[type=range].volume::-webkit-slider-thumb {
|
||||
margin-left: 0;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.progress input[type=range]::-moz-range-track {
|
||||
width: 100%;
|
||||
height: 8.4px;
|
||||
@ -272,9 +263,22 @@ video::-webkit-media-controls-enclosure {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.progress input[type=range].volume::-moz-range-thumb {
|
||||
border: 1px solid #fff;
|
||||
background: #fff;
|
||||
input[type=range]::-ms-track {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
input[type=range]::-ms-ticks {
|
||||
background: none;
|
||||
color: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
input[type=range]::-ms-thumb {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
input[type=range]::-ms-tooltip {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.seek {
|
||||
@ -294,9 +298,12 @@ video::-webkit-media-controls-enclosure {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.right-controls {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.bottom-controls {
|
||||
padding: 3px 4px 0px 4px;
|
||||
//padding: 5px 4px 5px 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@ -327,8 +334,8 @@ video::-webkit-media-controls-enclosure {
|
||||
align-items: center;
|
||||
}
|
||||
video[data-ckin="circle"] {
|
||||
-webkit-clip-path: ellipse(100px 100px at center);
|
||||
clip-path: ellipse(100px 100px at center);
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress-ring {
|
||||
position: absolute;
|
||||
@ -337,9 +344,7 @@ video[data-ckin="circle"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
.progress-ring__circle {
|
||||
transform-origin: center;
|
||||
transform: rotate(-90deg);
|
||||
transition: stroke-dashoffset 0.15s;
|
||||
transition: stroke-dashoffset;
|
||||
}
|
||||
|
||||
.ckin__player.circle {
|
||||
|
@ -480,7 +480,8 @@ input {
|
||||
position: relative;
|
||||
padding-left: 67px;
|
||||
min-height: 54px;
|
||||
width: 256px;
|
||||
max-width: 286px;
|
||||
overflow: visible!important;
|
||||
|
||||
&-toggle, &-download {
|
||||
border-radius: 50%;
|
||||
@ -492,6 +493,28 @@ input {
|
||||
&-download {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&-waveform {
|
||||
height: 23px;
|
||||
|
||||
//overflow: visible!important;
|
||||
|
||||
rect {
|
||||
//overflow: visible!important;
|
||||
fill: #CBCBCB;
|
||||
|
||||
&.active {
|
||||
fill: $blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-time {
|
||||
font-size: 14px;
|
||||
color: $color-gray;
|
||||
margin-top: 4px;
|
||||
margin-left: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-signUp {
|
||||
|
Loading…
x
Reference in New Issue
Block a user