128 lines
3.1 KiB
JavaScript
128 lines
3.1 KiB
JavaScript
import { Synth } from '../../assets/js/synth.js'
|
|
|
|
class NavPrimary extends HTMLElement {
|
|
categories = []
|
|
subs = []
|
|
|
|
audioEngine = null
|
|
masterGain = null
|
|
|
|
menuVoices = {}
|
|
|
|
connectedCallback() {
|
|
this.setupAudio()
|
|
|
|
this.categories = this.querySelectorAll('nav-link')
|
|
this.subs = this.querySelectorAll('ul')
|
|
|
|
this.activate()
|
|
|
|
window.addEventListener('popstate', () => {
|
|
this.activate()
|
|
})
|
|
|
|
this.categories.forEach(n => {
|
|
this.setupVoice(n)
|
|
|
|
n.addEventListener('click', () => {
|
|
const category = n.attributes.getNamedItem('category')
|
|
const link = n.attributes.getNamedItem('link')
|
|
|
|
console.log(link)
|
|
|
|
if (link) {
|
|
history.pushState({}, '', link.value)
|
|
location.pathname = link.value
|
|
} else if (category) {
|
|
location.hash = category.value
|
|
}
|
|
})
|
|
|
|
n.addEventListener('mouseenter', () => {
|
|
const menuItem = this.querySelector('#menuItem h1')
|
|
menuItem.textContent = n.dataset.name
|
|
|
|
this.menuVoices[n.dataset.name].noteOn()
|
|
|
|
menuItem.classList.add('active')
|
|
})
|
|
|
|
n.addEventListener('mouseleave', () => {
|
|
const menuItem = this.querySelector('#menuItem h1')
|
|
|
|
this.menuVoices[n.dataset.name].noteOff()
|
|
|
|
menuItem.classList.remove('active')
|
|
})
|
|
})
|
|
|
|
const audioEl = this.querySelector('.audioToggle')
|
|
audioEl.addEventListener('click', () => this.toggleAudio())
|
|
}
|
|
|
|
activate() {
|
|
let active, toOpen
|
|
|
|
|
|
this.categories.forEach(c => {
|
|
const { value } = c.attributes.getNamedItem('category') || false
|
|
|
|
if (c.classList.contains('active')) {
|
|
c.classList.remove('active')
|
|
} else if (value == location.hash.replace('#', '')) {
|
|
c.classList.add('active')
|
|
}
|
|
})
|
|
|
|
this.subs.forEach(s => {
|
|
const { name } = s.dataset
|
|
|
|
if (name == location.hash.replace('#', '') || name == location.pathname) {
|
|
toOpen = s
|
|
} else if (s.classList.contains('active')){
|
|
active = s
|
|
}
|
|
})
|
|
|
|
if (active) {
|
|
active.addEventListener('transitionend', () => {
|
|
toOpen.classList.add('active')
|
|
}, { once: true })
|
|
|
|
active.classList.remove('active')
|
|
} else if (toOpen) {
|
|
toOpen.classList.add('active')
|
|
}
|
|
}
|
|
|
|
setupAudio() {
|
|
// AUDIO SETUP
|
|
this.audioEngine = new (window.AudioContext || window.webkitAudioContext)()
|
|
this.audioEngine.suspend()
|
|
this.masterGain = this.audioEngine.createGain()
|
|
|
|
this.masterGain.gain.value = 0.9
|
|
this.masterGain.connect(this.audioEngine.destination)
|
|
}
|
|
|
|
toggleAudio() {
|
|
const audioEl = this.querySelector('.audioToggle')
|
|
|
|
if (this.audioEngine.state == 'suspended') {
|
|
this.audioEngine.resume()
|
|
audioEl.classList.add('active')
|
|
} else {
|
|
this.audioEngine.suspend()
|
|
audioEl.classList.remove('active')
|
|
}
|
|
}
|
|
|
|
setupVoice(el) {
|
|
// create synthVoices per navItem
|
|
this.menuVoices[el.dataset.name] = new Synth(this.audioEngine)
|
|
this.menuVoices[el.dataset.name].gain.connect(this.masterGain)
|
|
}
|
|
}
|
|
|
|
customElements.define('nav-primary', NavPrimary)
|