Implements a Slide class #6

Merged
j merged 2 commits from refactor-class into master 2018-03-17 09:45:19 +00:00

View File

@ -1,5 +1,164 @@
class Slide {
constructor(slide, idx) {
this.isInit = false
this.el = slide
this.idx = idx
this.duration = slide.dataset.duration
const video = slide.querySelector('.video')
if (video) {
this.video = load_urls(video.dataset)
this.videoVolume = video.dataset.volume ? parseFloat(video.dataset.volume) : 1
this.videoContainer = video
if (this.video.length > 1) {
this.zooms = this.video.map(url => url.split('/').pop().split('#')[0].split(',').map(a => Math.round(a)))
}
}
const audio = slide.querySelector('.audio')
if (audio) {
this.audio = audio.dataset.url // audio does not need to be an array
this.audioVolume = audio.dataset.volume ? parseFloat(audio.dataset.volume) : 1
this.audioContainer = audio
this.audioContinue = !!audio.dataset.continue
}
this.initEmbeds()
return this
}
initEmbeds() {
if (this.video) {
const videoEmbed = this.videoEmbed = new PandoraEmbed({
id: 'slide-' + this.idx,
url: this.video[0],
container: this.videoContainer
})
videoEmbed.on('init', (data) => {
this.isVideoInit = true
})
videoEmbed.on('playing', (positionData) => {
if (!this.videoStart) {
this.videoStart = positionData.position
}
})
}
if (this.audio) {
const audioEmbed = this.audioEmbed = new PandoraEmbed({
id: 'audio-' + this.idx,
url: this.audio,
container: this.audioContainer
})
audioEmbed.on('init', (data) => {
this.isAudioInit = true
})
audioEmbed.on('playing', (positionData) => {
if (!this.audioStart) {
this.audioStart = positionData.position
}
})
}
return this;
}
sendToBack() {
this.el.style.zIndex = 0
return this
}
bringToFront() {
this.el.style.zIndex = 10
return this
}
start() {
if (this.zooms) {
this.startZoom()
} else if (this.video && this.video.length) {
this.startVideo()
}
if (this.audioContainer) { // if there is an audio container, we always stop current audio
reset_active_audio()
}
if (this.audio) {
this.startAudio()
}
return this
}
stop() {
if (this.zooms) {
this.resetZoom()
} else if (this.video && this.video.length) {
this.resetVideo()
}
if (this.audio && !this.audioContinue) {
this.resetAudio()
}
return this
}
startZoom() {
for (var i=1; i<this.zooms.length; i++) {
this.zoomTimeouts = [];
((j) => {
this.zoomTimeouts.push(setTimeout(() => {
this.videoEmbed.postMessage('options', {
'area': this.zooms[j]
})
}, Math.round(1000 * (this.duration / this.zooms.length) * j)))
})(i);
}
return this
}
startVideo() {
this.videoEmbed.postMessage('options', {
'paused': false,
'volume': this.videoVolume
})
return this
}
startAudio() {
this.audioEmbed.postMessage('options', {
'paused': false,
'volume': this.audioVolume
})
activeAudio = this
return this
}
resetZoom() {
this.zoomTimeouts.forEach(timeout => clearTimeout(timeout))
this.videoEmbed.postMessage('options', {
'area': this.zooms[0]
})
return this
}
resetVideo() {
this.videoEmbed.postMessage('options', {
'paused': true,
'position': this.start || 0
})
return this
}
resetAudio() {
this.audioEmbed.postMessage('options', {
'paused': true,
'position': 0 //FIXME: figure correct audio reset
})
activeAudio = null;
return this
}
}
var slides = [], var slides = [],
slideData = [],
current = 0, current = 0,
activeAudio, activeAudio,
timeout; timeout;
@ -8,33 +167,25 @@ var slides = [],
init() init()
function init() { function init() {
document.querySelectorAll('.slide').forEach(function(slide) { document.querySelectorAll('.slide').forEach(function(slide, idx) {
slides.push(slide) slides.push(new Slide(slide, idx))
var data = slideData[slides.length - 1] = load_slide(slide);
data.idx = slides.length - 1;
if (data.video && data.video.length) {
data.embed = init_embed(data)
}
if (data.audio) {
data.audioEmbed = init_audio_embed(data)
}
}) })
go(0) go(0)
} }
function go(idx) { function go(idx) {
var old = current var old = current
slides[current].style.zIndex = 0 slides[current].sendToBack()
slides[idx].style.zIndex = 10 slides[idx].bringToFront()
current = idx current = idx
if (timeout) { if (timeout) {
clearTimeout(timeout) clearTimeout(timeout)
timeout = null timeout = null
} }
timeout = setTimeout(next, Math.round(slides[current].dataset.duration) * 1000) timeout = setTimeout(next, Math.round(slides[current].duration) * 1000)
stop(old) slides[old].stop()
start(current) slides[current].start()
} }
function next() { function next() {
@ -51,34 +202,6 @@ function previous() {
go(idx) go(idx)
} }
function start(idx) {
var data = slideData[idx]
console.log('start', current, data)
if (data.zooms) {
start_zoom(data)
} else if (data.video && data.video.length) {
start_video(data)
}
if (data.audioContainer) { // if there is an audio container, we always stop current audio
reset_active_audio();
}
if (data.audio) {
start_audio(data)
}
}
function stop(idx) {
var data = slideData[idx]
console.log(current, data)
if (data.zooms) {
reset_zoom(data)
} else if (data.video && data.video.length) {
reset_video(data)
}
if (data.audio && !data.audioContinue) {
reset_audio(data)
}
}
function load_urls(dataset) { function load_urls(dataset) {
var urls = [], idx = 0 var urls = [], idx = 0
@ -89,56 +212,6 @@ function load_urls(dataset) {
return urls return urls
} }
function load_slide(slide) {
var data = {}
data.duration = slide.dataset.duration
var video = slide.querySelector('.video')
if (video) {
data.video = load_urls(video.dataset)
data.videoVolume = video.dataset.volume ? parseFloat(video.dataset.volume) : 1
data.container = video
// assumes documents if length > 1
if (data.video.length > 1) {
data.zooms = data.video.map(url => url.split('/').pop().split('#')[0].split(',').map(a => Math.round(a)))
}
}
var audio = slide.querySelector('.audio')
if (audio) {
data.audio = audio.dataset.url // audio does not need to be an array
data.audioVolume = audio.dataset.volume ? parseFloat(audio.dataset.volume) : 1
data.audioContainer = audio
console.log('continue', audio.dataset.continue)
data.audioContinue = !!audio.dataset.continue
}
return data
}
function init_embed(data) {
var embed = window.currentEmbed = new PandoraEmbed({
id: 'slide-' + data.idx,
url: data.video[0],
container: data.container
});
embed.on('init', function(data) {
});
embed.on('playing', function(positionData) {
if (!slideData[data.idx].start) {
slideData[data.idx].start = positionData.position;
}
});
return embed;
}
function init_audio_embed(data) {
return new PandoraEmbed({
id: 'slide-audio-' + data.idx,
url: data.audio,
container: data.audioContainer
})
}
window.addEventListener('blur', function(){ window.addEventListener('blur', function(){
setTimeout(function(){ setTimeout(function(){
@ -150,62 +223,9 @@ window.addEventListener('blur', function(){
}, false); }, false);
function reset_zoom(data) {
data.zoomTimeouts.forEach(timeout => clearTimeout(timeout))
data.embed.postMessage('options', {
'area': data.zooms[0]
})
}
function start_zoom(data) {
// console.log('start zoon', Math.round(1000 * data.duration / 2))
for (var i=1; i<data.zooms.length; i++) {
data.zoomTimeouts = [];
(function(j) {
data.zoomTimeouts.push(setTimeout(function() {
data.embed.postMessage('options', {
'area': data.zooms[j]
})
}, Math.round(1000 * (data.duration / data.zooms.length) * j)))
})(i)
}
}
function start_video(data) {
data.embed.postMessage('options', {
'paused': false,
'volume': data.videoVolume
})
}
function start_audio(data) {
data.audioEmbed.postMessage('options', {
'paused': false,
'volume': data.audioVolume
})
activeAudio = data
}
function reset_video(data) {
data.embed.postMessage('options', {
'paused': true,
'position': data.start || 0
})
}
function reset_audio(data) {
data.audioEmbed.postMessage('options', {
'paused': true,
'position': 0 //FIXME: figure correct audio reset
})
activeAudio = null;
}
function reset_active_audio() { function reset_active_audio() {
if (activeAudio) { if (activeAudio) {
reset_audio(activeAudio) activeAudio.resetAudio()
} }
} }