functionality mostly there, synth applied to menu, layout working
This commit is contained in:
parent
b33f264c61
commit
c45be77272
12
.eleventy.js
12
.eleventy.js
|
@ -1,8 +1,14 @@
|
|||
const pluginWebc = require('@11ty/eleventy-plugin-webc')
|
||||
const markdownIt = require('markdown-it')
|
||||
const mdla = require('markdown-it-link-attributes')
|
||||
// node requires
|
||||
const fs = require('fs')
|
||||
|
||||
// webc plugin
|
||||
const pluginWebc = require('@11ty/eleventy-plugin-webc')
|
||||
|
||||
// markdown plugin
|
||||
const markdownIt = require('markdown-it')
|
||||
const mdla = require('markdown-it-link-attributes')
|
||||
|
||||
// ~> config start
|
||||
module.exports = (config) => {
|
||||
// webc
|
||||
config.addPlugin(pluginWebc, {
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
<style @raw="getBundle('css')" webc:keep></style>
|
||||
<script type="module" @raw="getBundle('js')" webc:keep></script>
|
||||
|
||||
<!-- javascript -->
|
||||
<!-- <script src="../assets/js/script.js" type="module" webc:keep></script> -->
|
||||
<!-- tracking -->
|
||||
</head>
|
||||
|
||||
|
|
|
@ -9,9 +9,7 @@ class NavLink extends HTMLElement {
|
|||
span.nextSibling.remove()
|
||||
}
|
||||
this.nextSibling.remove()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
customElements.define('nav-link', NavLink)
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
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')
|
||||
|
||||
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)
|
|
@ -1,5 +1,5 @@
|
|||
<nav id="primary">
|
||||
<nav-link link="/" data-name="~"><~</nav-link>
|
||||
<nav-link link="/" data-name="<~"><~</nav-link>
|
||||
<nav-link webc:for="c in categories" :category="c" :data-name="c"></nav-link>
|
||||
|
||||
<button class="audioToggle"></button>
|
||||
|
@ -13,7 +13,7 @@
|
|||
</ul>
|
||||
</nav>
|
||||
|
||||
<section style="position: fixed; bottom: 0; left: 0; margin: 0; padding: 0; width: 100vw; height: 0px; overflow: visible; z-index: 100;mix-blend-mode: difference;">
|
||||
<section id="menuItem" style="">
|
||||
<h1 id="menuItem"></h1>
|
||||
</section>
|
||||
|
||||
|
@ -21,76 +21,17 @@
|
|||
<span>top</span>
|
||||
</nav>
|
||||
|
||||
<script type="module">
|
||||
class NavPrimary extends HTMLElement {
|
||||
categories = []
|
||||
subs = []
|
||||
|
||||
connectedCallback() {
|
||||
this.categories = this.querySelectorAll('nav-link')
|
||||
this.subs = this.querySelectorAll('ul')
|
||||
|
||||
this.activate()
|
||||
|
||||
window.addEventListener('popstate', (evt) => {
|
||||
this.activate()
|
||||
})
|
||||
|
||||
this.categories.forEach(n => {
|
||||
n.addEventListener('click',() => {
|
||||
const category = n.attributes.getNamedItem('category')
|
||||
const link = n.attributes.getNamedItem('link')
|
||||
|
||||
if (link) {
|
||||
history.pushState({}, '', link.value)
|
||||
location.pathname = link.value
|
||||
} else if (category) {
|
||||
location.hash = category.value
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.categories.forEach(i => {
|
||||
const { value } = i.attributes.getNamedItem('category') || i.attributes.getNamedItem('link')
|
||||
|
||||
if (value != '/' && (value == location.hash.replace('#', '') || value == location.pathname)) {
|
||||
i.classList.add('active')
|
||||
} else {
|
||||
i.classList.remove('active')
|
||||
}
|
||||
})
|
||||
|
||||
this.subs.forEach(s => {
|
||||
const { name } = s.dataset
|
||||
|
||||
if (name == location.hash.replace('#', '') || name == location.pathname) {
|
||||
s.classList.add('active')
|
||||
} else {
|
||||
s.classList.remove('active')
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('nav-primary', NavPrimary)
|
||||
</script>
|
||||
<script src="nav-primary.js" type="module"></script>
|
||||
|
||||
<style webc:scoped>
|
||||
/* => CONTAINER */
|
||||
nav {
|
||||
display: flex;
|
||||
gap: 0.25em;
|
||||
margin: 1em var(--page-margin-inline) 0.5em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
/* => LINKS */
|
||||
nav-link {
|
||||
padding-inline: 0.125em;
|
||||
}
|
||||
|
||||
/* => AUDIO TOGGLE */
|
||||
.audioToggle {
|
||||
background: none;
|
||||
|
@ -130,4 +71,38 @@ nav-link {
|
|||
ul.active {
|
||||
max-height: 50vh !important;
|
||||
}
|
||||
|
||||
/* => POPUP TITLE */
|
||||
#menuItem {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100vw;
|
||||
height: 0px;
|
||||
overflow: visible;
|
||||
z-index: 100;
|
||||
mix-blend-mode: difference;
|
||||
}
|
||||
|
||||
#menuItem h1 {
|
||||
position: absolute;
|
||||
line-height: inherit;
|
||||
bottom: -500px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 33vw;
|
||||
opacity: 0;
|
||||
transform: translateY(100px);
|
||||
transform-origin: bottom left;
|
||||
mix-blend-mode: difference;
|
||||
transition: opacity ease-in-out 0.1s, transform ease-in-out 0.1s;
|
||||
}
|
||||
|
||||
#menuItem h1.active {
|
||||
mix-blend-mode: difference;
|
||||
opacity: 1 !important;
|
||||
transform: translateY(-600px) !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,14 +3,14 @@ layout: base.webc
|
|||
---
|
||||
|
||||
<section class="page">
|
||||
<div :if="imgFeat" class="imgFeat">
|
||||
<img src="{{imgFeat}}" alt="">
|
||||
<div webc:if="imgFeat" class="imgFeat">
|
||||
<img :src="imgFeat" alt="">
|
||||
</div>
|
||||
|
||||
<section class="text {{url}}" @raw="content">
|
||||
<section class="text" @raw="content">
|
||||
</section>
|
||||
|
||||
<section :if="gallery" class="imgs">
|
||||
<img for="img of gallery" src="{{img}}" alt="">
|
||||
<section webc:if="gallery" class="imgs">
|
||||
<img webc:for="img of gallery" :src="img" alt="">
|
||||
</section class="imgs">
|
||||
</section>
|
||||
|
|
|
@ -114,27 +114,6 @@ nav#toTop.active > span:hover {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
h1#menuItem {
|
||||
position: absolute;
|
||||
line-height: inherit;
|
||||
bottom: -500px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 33vw;
|
||||
opacity: 0;
|
||||
transform: translateY(100px);
|
||||
transform-origin: bottom left;
|
||||
mix-blend-mode: difference;
|
||||
transition: opacity ease-in-out 0.1s, transform ease-in-out 0.1s;
|
||||
}
|
||||
|
||||
h1#menuItem.active {
|
||||
mix-blend-mode: difference;
|
||||
opacity: 1 !important;
|
||||
transform: translateY(-600px) !important;
|
||||
}
|
||||
|
||||
|
||||
/* --> MAINPAGE CONSTRUCTION <-- */
|
||||
nav#sub > ul {
|
||||
margin: 0;
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
import {Synth} from '/assets/js/synth.js'
|
||||
|
||||
// audio for events
|
||||
// AUDIO SETUP
|
||||
const audioEngine = new (window.AudioContext || window.webkitAudioContext)()
|
||||
audioEngine.suspend()
|
||||
const masterGain = audioEngine.createGain()
|
||||
const audioEl = document.querySelector('#audioToggle')
|
||||
let audioAllowed = true
|
||||
|
||||
masterGain.gain.value = 0.9
|
||||
masterGain.connect(audioEngine.destination)
|
||||
|
||||
const audioToggle = () => {
|
||||
audioEl.classList.toggle('active')
|
||||
if (audioEngine.state == 'suspended') {
|
||||
audioEngine.resume()
|
||||
audioAllowed = true
|
||||
} else {
|
||||
audioEngine.suspend()
|
||||
audioAllowed = false
|
||||
}
|
||||
}
|
||||
|
||||
const audioEnable = () => {
|
||||
if (audioEngine.state == 'suspended' && audioAllowed) {
|
||||
audioEngine.resume()
|
||||
}
|
||||
}
|
||||
|
||||
audioEl.addEventListener('click', audioToggle)
|
||||
|
||||
// NAVIGATION
|
||||
let primaryNav = document.querySelectorAll('nav#primary>span')
|
||||
let subNav = document.querySelector('nav#sub')
|
||||
let menuItem = document.querySelector('#menuItem')
|
||||
|
||||
let menuVoices = []
|
||||
|
||||
// check if any primaryNav items are active
|
||||
const primaryActive = () => {
|
||||
let active = false
|
||||
for (let n of primaryNav) {
|
||||
if (n.classList.contains('active')) {
|
||||
active = true
|
||||
}
|
||||
}
|
||||
return active
|
||||
}
|
||||
|
||||
for (let n of primaryNav) {
|
||||
// remove shitty firefox span spacing
|
||||
n.nextSibling.parentNode.removeChild(n.nextSibling)
|
||||
|
||||
// create synthVoices per navItem
|
||||
menuVoices[n.dataset.link] = new Synth(audioEngine)
|
||||
menuVoices[n.dataset.link].gain.connect(masterGain)
|
||||
|
||||
// primary navigation click events
|
||||
n.addEventListener('click', (e) => {
|
||||
for (let _n of primaryNav) {
|
||||
if (n === _n && n.dataset.link != '~') {
|
||||
n.classList.toggle('active')
|
||||
} else if (n.dataset.link == '~') {
|
||||
window.location.href = '/'
|
||||
} else {
|
||||
_n.classList.remove('active')
|
||||
}
|
||||
}
|
||||
|
||||
// subnav is nav element
|
||||
if (primaryActive()) {
|
||||
subNav.classList.add('active')
|
||||
} else {
|
||||
subNav.classList.remove('active')
|
||||
}
|
||||
|
||||
for (let s of subNav.children) {
|
||||
if (s.id == n.dataset.link && primaryActive()) {
|
||||
s.classList.add('active')
|
||||
} else {
|
||||
s.classList.remove('active')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// mouseover on primary nav for big botom text
|
||||
n.addEventListener('mouseenter', () => {
|
||||
// unsuspend sound on mouseenter
|
||||
audioEnable()
|
||||
|
||||
if (n.dataset.link == '~') {
|
||||
menuItem.textContent = '\u003C\u007E'
|
||||
} else {
|
||||
menuItem.textContent = n.dataset.link
|
||||
}
|
||||
menuItem.className = 'active'
|
||||
menuVoices[n.dataset.link].noteOn()
|
||||
})
|
||||
|
||||
n.addEventListener('mouseout', () => {
|
||||
menuItem.className = 'inactive'
|
||||
menuVoices[n.dataset.link].noteOff()
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
// SCROLL TO TOP NAVIGATION
|
||||
const toTop = document.querySelector('nav#toTop')
|
||||
|
||||
toTop.addEventListener('click', (e) => {
|
||||
window.scrollTo(0,0)
|
||||
})
|
||||
|
||||
window.addEventListener('scroll', (e) => {
|
||||
let scrollY = window.scrollY
|
||||
if (scrollY > 50) {
|
||||
toTop.classList.add('active')
|
||||
} else {
|
||||
toTop.classList.remove('active')
|
||||
}
|
||||
})
|
|
@ -1,11 +0,0 @@
|
|||
// importing scripts
|
||||
import '/assets/js/interaction.js'
|
||||
|
||||
// 'page' load transitions
|
||||
const pageSection = document.querySelector('section.page')
|
||||
|
||||
pageSection.addEventListener('load', (e) => {
|
||||
console.log('div loaded?')
|
||||
console.log(e.target)
|
||||
alert('ehllo')
|
||||
})
|
|
@ -60,5 +60,4 @@ export class Synth {
|
|||
// release
|
||||
this.modGain.gain.setTargetAtTime(0.8, this.audio.currentTime + 0.4, 0.5)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue