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('#sub 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('category click', link, category) 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') } }) console.log(this.subs) 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)