import {$id, $class, $query} from './utils'
class Music
# Play button classes
playingClass: 'play-button_playing'
pauseClass: 'play-button_pause'
transitioningClass: 'play-button_transitioning'
# Songs container
music: undefined
# Audio element
player: undefined
# Main play button
playButton: undefined
# This can't be assigned immediately cause chrome doesn't like audio context to be started immediately
audio: undefined
analyzer: undefined
bufferLength: undefined
dataArray: undefined
source: undefined
constructor: (@fft) ->
@music = $id 'music'
@player = $id 'player'
@playButton = $id 'play-button'
if @music
# Don't blow up people's eardrums
@player.volume = 0.1
@player.preload= 'metadata'
@player.crossOrigin = 'anonymous'
# Get songs
songs = @music.getElementsByClassName 'song'
self = @
do (self) ->
self.playButton.addEventListener 'click', ->
if self.player.src
if self.player.paused
playing = $query(".#{self.playingClass}")
if playing
playing.classList.add self.pauseClass
self.playButton.classList.add self.pauseClass
do self.player.play
else
do self.pauseAll
do self.player.pause
for song in songs
do (song) ->
song.addEventListener 'click', ->
# Can't reuse audio analyzer
if self.audio is undefined
self.audio = new (window.AudioContext || window.webkitAudioContext)();
self.analyzer = self.audio.createAnalyser();
self.analyzer.fftSize = self.fft * 2;
self.bufferLength = self.analyzer.frequencyBinCount;
self.dataArray = new Uint8Array(self.bufferLength);
button = song.querySelector('.play-button')
same = self.player.src isnt song.dataset.url
if same or self.player.paused
do self.pauseAll
playing = $query(".#{self.playingClass}")
if playing
playing.classList.remove self.playingClass
button.classList.add self.playingClass
button.classList.add self.pauseClass
self.playButton.classList.add self.pauseClass
self.playButton.parentNode.classList.remove 'menu__button_hidden'
if same
self.player.src = song.dataset.url
if self.source is undefined
self.source = self.audio.createMediaElementSource(self.player)
self.source.connect(self.analyzer)
self.analyzer.connect(self.audio.destination)
do self.player.play
else
do self.pauseAll
do self.player.pause
pauseAll: =>
buttons = $class 'play-button'
self = @
for button in buttons
do (self, button) ->
if button.classList.contains self.pauseClass
button.classList.remove self.pauseClass
button.classList.add self.transitioningClass
setTimeout ->
button.classList.remove self.transitioningClass
return
, 300
return
export default Music