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')
|
// node requires
|
||||||
const markdownIt = require('markdown-it')
|
|
||||||
const mdla = require('markdown-it-link-attributes')
|
|
||||||
const fs = require('fs')
|
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) => {
|
module.exports = (config) => {
|
||||||
// webc
|
// webc
|
||||||
config.addPlugin(pluginWebc, {
|
config.addPlugin(pluginWebc, {
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
<style @raw="getBundle('css')" webc:keep></style>
|
<style @raw="getBundle('css')" webc:keep></style>
|
||||||
<script type="module" @raw="getBundle('js')" webc:keep></script>
|
<script type="module" @raw="getBundle('js')" webc:keep></script>
|
||||||
|
|
||||||
<!-- javascript -->
|
|
||||||
<!-- <script src="../assets/js/script.js" type="module" webc:keep></script> -->
|
|
||||||
<!-- tracking -->
|
<!-- tracking -->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,7 @@ class NavLink extends HTMLElement {
|
||||||
span.nextSibling.remove()
|
span.nextSibling.remove()
|
||||||
}
|
}
|
||||||
this.nextSibling.remove()
|
this.nextSibling.remove()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('nav-link', NavLink)
|
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 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>
|
<nav-link webc:for="c in categories" :category="c" :data-name="c"></nav-link>
|
||||||
|
|
||||||
<button class="audioToggle"></button>
|
<button class="audioToggle"></button>
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</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>
|
<h1 id="menuItem"></h1>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -21,76 +21,17 @@
|
||||||
<span>top</span>
|
<span>top</span>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<script type="module">
|
<script src="nav-primary.js" type="module"></script>
|
||||||
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>
|
|
||||||
|
|
||||||
<style webc:scoped>
|
<style webc:scoped>
|
||||||
/* => CONTAINER */
|
/* => CONTAINER */
|
||||||
nav {
|
nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 0.25em;
|
||||||
margin: 1em var(--page-margin-inline) 0.5em;
|
margin: 1em var(--page-margin-inline) 0.5em;
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* => LINKS */
|
|
||||||
nav-link {
|
|
||||||
padding-inline: 0.125em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* => AUDIO TOGGLE */
|
/* => AUDIO TOGGLE */
|
||||||
.audioToggle {
|
.audioToggle {
|
||||||
background: none;
|
background: none;
|
||||||
|
@ -130,4 +71,38 @@ nav-link {
|
||||||
ul.active {
|
ul.active {
|
||||||
max-height: 50vh !important;
|
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>
|
</style>
|
||||||
|
|
|
@ -3,14 +3,14 @@ layout: base.webc
|
||||||
---
|
---
|
||||||
|
|
||||||
<section class="page">
|
<section class="page">
|
||||||
<div :if="imgFeat" class="imgFeat">
|
<div webc:if="imgFeat" class="imgFeat">
|
||||||
<img src="{{imgFeat}}" alt="">
|
<img :src="imgFeat" alt="">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section class="text {{url}}" @raw="content">
|
<section class="text" @raw="content">
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section :if="gallery" class="imgs">
|
<section webc:if="gallery" class="imgs">
|
||||||
<img for="img of gallery" src="{{img}}" alt="">
|
<img webc:for="img of gallery" :src="img" alt="">
|
||||||
</section class="imgs">
|
</section class="imgs">
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -114,27 +114,6 @@ nav#toTop.active > span:hover {
|
||||||
cursor: pointer;
|
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 <-- */
|
/* --> MAINPAGE CONSTRUCTION <-- */
|
||||||
nav#sub > ul {
|
nav#sub > ul {
|
||||||
margin: 0;
|
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
|
// release
|
||||||
this.modGain.gain.setTargetAtTime(0.8, this.audio.currentTime + 0.4, 0.5)
|
this.modGain.gain.setTargetAtTime(0.8, this.audio.currentTime + 0.4, 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue