Global pause / resume #12

Open
sanj wants to merge 1 commits from global-pause into master
2 changed files with 117 additions and 5 deletions

View File

@ -17,6 +17,14 @@ body {
height: 100%;
}
#overlay {
z-index: 9999;
background: transparent;
position: absolute;
width: 100%;
height: 100%;
}
.slide {
z-index: 0;
position: absolute;

View File

@ -4,6 +4,7 @@ class Slide {
this.el = slide
this.idx = idx
this.duration = slide.dataset.duration
this.durationMs = parseInt(this.duration) * 1000
const video = slide.querySelector('.video')
if (video) {
this.video = load_urls(video.dataset)
@ -100,6 +101,8 @@ class Slide {
start() {
console.log('called start', this.isReady())
this.timeout = setTimeout(next, this.durationMs)
this.startTime = new Date()
if (this.zooms) {
this.startZoom()
} else if (this.video && this.video.length) {
@ -126,15 +129,52 @@ class Slide {
return this
}
startZoom() {
pause() {
clearTimeout(this.timeout)
this.pauseTime = new Date()
if (this.zooms) {
this.pauseZoom()
} else if (this.video && this.video.length) {
this.pauseVideo()
}
if (this.audio) {
this.pauseAudio()
}
}
resume() {
const offset = this.pauseTime - this.startTime
const timeout = this.durationMs - offset
this.timeout = setTimeout(next, timeout)
// "Fake" the start time in case the user pauses and resumes again.
// NOTE: This seems like a bit of a hack, but the other way seemed convoluted
this.startTime = new Date() - offset
if (this.zooms) {
this.resumeZoom()
} else if (this.video && this.video.length) {
this.resumeVideo()
}
if (this.audio) {
this.resumeAudio()
}
}
startZoom(offset) {
offset = offset || 0
for (var i=1; i<this.zooms.length; i++) {
this.zoomTimeouts = [];
((j) => {
const timeout = Math.round(1000 * (this.duration / this.zooms.length) * j) - offset
if (timeout < 0) return
this.zoomTimeouts.push(setTimeout(() => {
this.videoEmbed.postMessage('options', {
'area': this.zooms[j]
})
}, Math.round(1000 * (this.duration / this.zooms.length) * j)))
}, timeout))
})(i);
}
return this
@ -157,8 +197,47 @@ class Slide {
return this
}
pauseZoom() {
this.zoomTimeouts.forEach(clearTimeout)
return this
}
pauseVideo() {
this.videoEmbed.postMessage('options', {
'paused': true
})
return this
}
pauseAudio() {
this.audioEmbed.postMessage('options', {
'paused': true
})
return this
}
resumeZoom() {
const offset = this.pauseTime - this.startTime
this.startZoom(offset)
return this
}
resumeVideo() {
this.videoEmbed.postMessage('options', {
'paused': false
})
return this
}
resumeAudio() {
this.audioEmbed.postMessage('options', {
'paused': false
})
return this
}
resetZoom() {
this.zoomTimeouts.forEach(timeout => clearTimeout(timeout))
this.zoomTimeouts.forEach(clearTimeout)
this.videoEmbed.postMessage('options', {
'area': this.zooms[0]
})
@ -188,6 +267,8 @@ var slides = [],
activeAudio,
timeout;
let globalIsPaused = false
let textbUrl = new URLSearchParams(window.location.search).get('textb') || 'https://textb.org/r/housingplaylist2/'
// use raw version of page
@ -215,12 +296,33 @@ function loadYaml(txt) {
.join('')
document.body.innerHTML = `
<div class="base"></div>
<div id="overlay"></div>
${html}
`
return true
}
function globalPause() {
if (globalIsPaused) return;
slides[current].pause()
globalIsPaused = true
}
function globalResume() {
if (!globalIsPaused) return;
slides[current].resume()
globalIsPaused = false
}
function togglePause() {
if (globalIsPaused) {
globalResume()
} else {
globalPause()
}
}
function init() {
document.querySelectorAll('.slide').forEach(function(slide, idx) {
slides.push(new Slide(slide, idx))
@ -244,7 +346,7 @@ function go(idx) {
clearTimeout(timeout)
timeout = null
}
timeout = setTimeout(next, Math.round(slides[current].duration) * 1000)
// timeout = setTimeout(next, Math.round(slides[current].duration) * 1000)
slides[old].stop()
slides[current].start()
@ -298,5 +400,7 @@ document.addEventListener('keydown', function(event) {
} else if (event.key == 'ArrowLeft') {
previous()
event.preventDefault()
} else if (event.keyCode === 32) { // spacebar
togglePause()
}
}, false)