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
Showing only changes of commit 489722e8be - Show all commits

View File

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

View File

@ -4,6 +4,7 @@ class Slide {
this.el = slide this.el = slide
this.idx = idx this.idx = idx
this.duration = slide.dataset.duration this.duration = slide.dataset.duration
this.durationMs = parseInt(this.duration) * 1000
const video = slide.querySelector('.video') const video = slide.querySelector('.video')
if (video) { if (video) {
this.video = load_urls(video.dataset) this.video = load_urls(video.dataset)
@ -100,6 +101,8 @@ class Slide {
start() { start() {
console.log('called start', this.isReady()) console.log('called start', this.isReady())
this.timeout = setTimeout(next, this.durationMs)
this.startTime = new Date()
if (this.zooms) { if (this.zooms) {
this.startZoom() this.startZoom()
} else if (this.video && this.video.length) { } else if (this.video && this.video.length) {
@ -126,15 +129,52 @@ class Slide {
return this 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++) { for (var i=1; i<this.zooms.length; i++) {
this.zoomTimeouts = []; this.zoomTimeouts = [];
((j) => { ((j) => {
const timeout = Math.round(1000 * (this.duration / this.zooms.length) * j) - offset
if (timeout < 0) return
this.zoomTimeouts.push(setTimeout(() => { this.zoomTimeouts.push(setTimeout(() => {
this.videoEmbed.postMessage('options', { this.videoEmbed.postMessage('options', {
'area': this.zooms[j] 'area': this.zooms[j]
}) })
}, Math.round(1000 * (this.duration / this.zooms.length) * j))) }, timeout))
})(i); })(i);
} }
return this return this
@ -157,8 +197,47 @@ class Slide {
return this 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() { resetZoom() {
this.zoomTimeouts.forEach(timeout => clearTimeout(timeout)) this.zoomTimeouts.forEach(clearTimeout)
this.videoEmbed.postMessage('options', { this.videoEmbed.postMessage('options', {
'area': this.zooms[0] 'area': this.zooms[0]
}) })
@ -188,6 +267,8 @@ var slides = [],
activeAudio, activeAudio,
timeout; timeout;
let globalIsPaused = false
let textbUrl = new URLSearchParams(window.location.search).get('textb') || 'https://textb.org/r/housingplaylist2/' let textbUrl = new URLSearchParams(window.location.search).get('textb') || 'https://textb.org/r/housingplaylist2/'
// use raw version of page // use raw version of page
@ -215,12 +296,33 @@ function loadYaml(txt) {
.join('') .join('')
document.body.innerHTML = ` document.body.innerHTML = `
<div class="base"></div> <div class="base"></div>
<div id="overlay"></div>
${html} ${html}
` `
return true 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() { function init() {
document.querySelectorAll('.slide').forEach(function(slide, idx) { document.querySelectorAll('.slide').forEach(function(slide, idx) {
slides.push(new Slide(slide, idx)) slides.push(new Slide(slide, idx))
@ -244,7 +346,7 @@ function go(idx) {
clearTimeout(timeout) clearTimeout(timeout)
timeout = null timeout = null
} }
timeout = setTimeout(next, Math.round(slides[current].duration) * 1000) // timeout = setTimeout(next, Math.round(slides[current].duration) * 1000)
slides[old].stop() slides[old].stop()
slides[current].start() slides[current].start()
@ -298,5 +400,7 @@ document.addEventListener('keydown', function(event) {
} else if (event.key == 'ArrowLeft') { } else if (event.key == 'ArrowLeft') {
previous() previous()
event.preventDefault() event.preventDefault()
} else if (event.keyCode === 32) { // spacebar
togglePause()
} }
}, false) }, false)