diff options
| author | lens <lens@neural.garden> | 2021-03-23 21:10:11 +0000 |
|---|---|---|
| committer | lens <lens@neural.garden> | 2021-03-23 21:10:11 +0000 |
| commit | cc1d0c52e104245f9f1c0d77eb24a5a33800be38 (patch) | |
| tree | 02d8483dfe47803525b926a43c582dcfbf61c5db /frontend/site/audio/audio.player.js | |
| parent | 81c673f058fda04b96baae7b2302f876479bc0a9 (diff) | |
| parent | 7a3ec205e001e4c071a67ecc5c375612fa72afdc (diff) | |
Merge branch 'master' of asdf.us:swimmer
Diffstat (limited to 'frontend/site/audio/audio.player.js')
| -rw-r--r-- | frontend/site/audio/audio.player.js | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/frontend/site/audio/audio.player.js b/frontend/site/audio/audio.player.js new file mode 100644 index 0000000..17edeee --- /dev/null +++ b/frontend/site/audio/audio.player.js @@ -0,0 +1,141 @@ +import { history } from 'site/store' + +export default class AudioPlayer { + files = {} + players = {} + current_background_id = 0 + + constructor() { + this.done = this.done.bind(this) + } + + load(graph) { + this.files = graph.uploads + .filter(upload => upload.tag === 'audio') + .reduce((accumulator, item) => { + accumulator[item.id] = item + return accumulator + }, {}) + } + + has(id) { + return ( + (id > 0) && + (id in this.files) + ) + } + + done(id) { + // console.log('remove', id) + delete this.players[id] + } + + playPage(page) { + const { background_audio_id, restart_audio } = page.settings + // console.log('playPage', page) + if ( + this.current_background_id + && this.current_background_id !== background_audio_id + && this.current_background_id in this.players + ) { + this.players[this.current_background_id].stop() + } + if (this.has(background_audio_id)) { + this.current_background_id = background_audio_id + this.playFile({ + id: background_audio_id, + type: 'background', + restart: !!restart_audio, + }) + } + } + + playTile({ tile, type }) { + let id = type === 'click' + ? tile.settings.audio_on_click_id + : type === 'hover' + ? tile.settings.audio_on_hover_id + : null + if (this.has(id)) { + this.playFile({ id, tile, type }) + } + } + + playFile({ id, tile, type, restart, loop }) { + const item = this.files[id] + if (id in this.players) { + if (restart) { + this.players[id].restart() + } + if (tile && !this.players[id].tile) { + this.players[id].tile = tile + this.players[id].type = type + } + return this.players[id] + } else { + this.players[id] = new Player({ + item, + tile, + type, + done: this.done + }) + this.players[id].play() + return this.players[id] + } + } +} + +class Player { + constructor({ item, tile, type, done }) { + this.item = item + this.tile = tile + this.type = type + this.done = done + this.audio = document.createElement('audio') + this.handleEnded = this.handleEnded.bind(this) + this.handleError = this.handleError.bind(this) + this.release = this.release.bind(this) + this.audio.addEventListener('ended', this.handleEnded) + this.audio.addEventListener('error', this.handleError) + this.audio.src = item.url + } + + release() { + if (this.type === 'click' && this.tile && this.tile.settings.navigate_when_audio_finishes) { + history.push(this.tile.href) + } + this.audio.removeEventListener('ended', this.handleEnded) + this.audio.removeEventListener('error', this.handleError) + this.done(this.item.id) + this.item = null + this.done = null + this.audio = null + } + + handleError(error) { + console.error(error) + this.release() + } + + handleEnded() { + if (this.type === 'background') { + this.restart() + } else { + this.release() + } + } + + play() { + this.audio.play() + } + + restart() { + this.audio.currentTime = 0 + this.audio.play() + } + + stop() { + this.audio.pause() + this.release() + } +} |
