summaryrefslogtreecommitdiff
path: root/docs/assets
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2019-01-07 23:01:11 +0100
committerJules Laplace <julescarbon@gmail.com>2019-01-07 23:01:11 +0100
commit4777c058469847cbe02eb2a24634b21ee37384fc (patch)
tree3fd87861241a75f59819bc0771eb3e97bd88e2f6 /docs/assets
parentd317978119fc0936d9c342edf47e55be230cd215 (diff)
move docs
Diffstat (limited to 'docs/assets')
-rw-r--r--docs/assets/css/css.css342
-rwxr-xr-xdocs/assets/fonts/NHaasGroteskTXPro-55Rg.ttfbin0 -> 275008 bytes
-rwxr-xr-xdocs/assets/fonts/NHaasGroteskTXPro-56It.ttfbin0 -> 306228 bytes
-rwxr-xr-xdocs/assets/fonts/NHaasGroteskTXPro-75Bd.ttfbin0 -> 300820 bytes
-rwxr-xr-xdocs/assets/fonts/NHaasGroteskTXPro-76BdIt.ttfbin0 -> 297312 bytes
-rwxr-xr-xdocs/assets/fonts/alarmclock.ttfbin0 -> 21664 bytes
-rwxr-xr-xdocs/assets/fonts/roadrage.ttfbin0 -> 341760 bytes
-rw-r--r--docs/assets/img/dreaming-city.jpgbin0 -> 125438 bytes
-rw-r--r--docs/assets/img/escape-from-neukoelln.jpgbin0 -> 167756 bytes
-rw-r--r--docs/assets/img/pause-button.pngbin0 -> 1174 bytes
-rw-r--r--docs/assets/img/pause-inv.pngbin0 -> 3208 bytes
-rw-r--r--docs/assets/img/pause.pngbin0 -> 1336 bytes
-rw-r--r--docs/assets/img/play-button.pngbin0 -> 1336 bytes
-rw-r--r--docs/assets/img/play-fill.pngbin0 -> 1801 bytes
-rw-r--r--docs/assets/img/play-inv.pngbin0 -> 1993 bytes
-rw-r--r--docs/assets/img/play.pngbin0 -> 1978 bytes
-rw-r--r--docs/assets/img/playbutton.psdbin0 -> 50227 bytes
-rw-r--r--docs/assets/img/xena-vectra-logo-sm.pngbin0 -> 9139 bytes
-rw-r--r--docs/assets/img/xena-vectra-logo.pngbin0 -> 30091 bytes
-rw-r--r--docs/assets/img/xenavectra.gifbin0 -> 41515 bytes
-rw-r--r--docs/assets/js/cielab.js70
-rw-r--r--docs/assets/js/player.js79
-rw-r--r--docs/assets/js/shards.js107
-rw-r--r--docs/assets/js/site.js72
-rw-r--r--docs/assets/js/sounds.js17
-rw-r--r--docs/assets/js/stars.js63
-rw-r--r--docs/assets/js/util.js139
-rw-r--r--docs/assets/sounds/click.mp3bin0 -> 2337 bytes
-rw-r--r--docs/assets/sounds/click.wavbin0 -> 142582 bytes
29 files changed, 889 insertions, 0 deletions
diff --git a/docs/assets/css/css.css b/docs/assets/css/css.css
new file mode 100644
index 0000000..6271eb3
--- /dev/null
+++ b/docs/assets/css/css.css
@@ -0,0 +1,342 @@
+@font-face {
+ font-family: nhg;
+ src: url(../fonts/NHaasGroteskTXPro-55Rg.ttf);
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: nhg;
+ src: url(../fonts/NHaasGroteskTXPro-56It.ttf);
+ font-weight: normal;
+ font-style: italic;
+}
+@font-face {
+ font-family: nhg;
+ src: url(../fonts/NHaasGroteskTXPro-75Bd.ttf);
+ font-weight: bold;
+ font-style: normal;
+}
+@font-face {
+ font-family: nhg;
+ src: url(../fonts/NHaasGroteskTXPro-76BdIt.ttf);
+ font-weight: bold;
+ font-style: italic;
+}
+.desktop .m,
+.mobile .d { display: none; }
+html, body {
+ margin: 0; padding: 0; width: 100%; height: 100%;
+ font-family: nhg, sans-serif;
+ color: rgba(255,255,255,0.9);
+}
+html {
+ background-color: rgb(0,0,0);
+ background-image: linear-gradient(rgba(20, 10, 0, 0.0), rgba(20, 10, 0, 1.0));
+ background-attachment: fixed;
+ transition: background-color 1s;
+}
+html.day {
+ background-color: rgb(80,10,60);
+}
+html.night {
+ background-color: rgb(8,10,30);
+}
+body {
+ background-color: rgba(0,0,0,0);
+ transition: background-color 1000ms, opacity 500ms;
+ opacity: 1;
+}
+body.loading {
+ background-color: rgba(255,128,192,1);
+ background-color: black;
+ opacity: 0;
+}
+body.fade {
+ opacity: 1;
+ background-color: black;
+ background-color: rgba(255,128,192,1);
+}
+.shards {
+ position: absolute;
+ top: 0; left: 0;
+ width: 100%; height: 100%;
+ overflow: hidden;
+ pointer-events: none;
+}
+.bgs {
+ position: absolute;
+ top: 50%; left: 50%;
+ opacity: 0.7;
+ transition: opacity 500ms;
+ perspective: 10000px;
+}
+.stars {
+ transition: all 500ms cubic-bezier(0,0,0,1);
+ transform: translateZ(0) scaleX(1) scaleY(1);
+}
+.stars.fade {
+ transform: translateZ(0) scaleX(1.03) scaleY(1.03);
+}
+.fade {
+ opacity: 0;
+}
+.bg {
+ position: absolute;
+ top: 0; left: 0;
+ transition: all 120s;
+}
+header {
+ background-color: rgba(40,20,30,0.9);
+ position: absolute;
+ width: 100%;
+ bottom: 100px;
+ left: 0;
+}
+p {
+ margin: 0; padding: 0;
+ line-height: 1.4;
+}
+p + p {
+ margin-top: 14px;ß
+}
+a {
+ text-decoration: none;
+ color: rgba(255,255,255,0.8);
+ transition: color 200ms;
+ border-bottom: 1px dotted;
+}
+.desktop a:hover {
+ color: rgba(255,255,255,1.0);
+}
+img {
+ max-width: 100%;
+}
+img.cover {
+ max-width: 300px;
+}
+.menu a {
+ margin-right: 10px;
+ border-bottom: 0;
+}
+.menu a.active {
+ border-bottom: 1px dotted;
+ color: rgba(255,255,255,1.0);
+}
+.logo {
+ width: 400px;
+ opacity: 0.8;
+ animation: fade 10s infinite;
+}
+.row {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+}
+h1 {
+ font-size: 32px;
+ margin: 0;
+ padding: 10px 20px;
+ letter-spacing: -2px;
+ text-transform: uppercase;
+ cursor: pointer;
+ opacity: 0.9;
+ transition: opacity 500ms;
+ color: white;
+}
+.desktop h1:hover {
+ opacity: 1;
+}
+h2 {
+ margin: 0;
+ padding: 0 0 15px 0;
+ letter-spacing: -1px;
+}
+h3 {
+ margin: 0;
+ padding: 0 0 6px 0;
+ letter-spacing: 1px;
+ font-weight: normal;
+ font-style: italic;
+ font-size: 14px;
+ text-transform: uppercase;
+ opacity: 0.7;
+}
+ul {
+ margin: 0 0 20px 0;
+ padding: 0;
+ list-style-type: none;
+}
+ul li {
+ list-style-type: none;
+ line-height: 1.4;
+}
+ol {
+ margin: 0 0 20px 0;
+ padding: 0;
+}
+ol li {
+ line-height: 1.4;
+}
+.player {
+ padding: 12px 20px;
+ width: 300px;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+ cursor: pointer;
+ border-left: 1px solid #000;
+}
+.player .icon {
+ width: 1.2em;
+ height: 1.2em;
+ background-image: url(../img/pause-inv.png);
+ background-size: 100%;
+ background-position: center;
+ border: 2px solid rgba(255,255,255,0.3);
+ border-radius: 100%;
+ margin: 0 10px 0 10px;
+}
+.player.playing .icon {
+ background-image: url(../img/pause-inv.png);
+}
+.player.paused .icon {
+ background-image: url(../img/play-inv.png);
+}
+.player .track {
+ transition: all 100ms;
+ flex: auto;
+}
+.desktop .player:hover .track {
+ color: rgba(255,255,255,1.0);
+}
+.playlist {
+ -webkit-overflow-scrolling: touch;
+ overflow-y: auto;
+ max-height: calc(100vh - 140px);
+ width: 331px;
+ max-width: calc(100vw - 30px);
+ background: black;
+ position: absolute;
+ bottom: 160px; right: 0;
+ margin: 0px 10px;
+ padding: 0px;
+ height: 0; overflow: hidden;
+ transition: all 0.5s cubic-bezier(0,1,1,1);
+}
+.playlist.visible {
+ height: 180px;
+}
+.playlist ul {
+ margin: 0; padding: 0;
+}
+.playlist li {
+ margin: 0; padding: 10px;
+ cursor: pointer;
+ transition: all 0.2s;
+ background: rgba(20,5,10,0.5);
+}
+.playlist li.active {
+ color: #000;
+ background: rgba(255,255,255,0.9);
+}
+.playlistToggle {
+ align-self: flex-end;
+ width: 15px;
+ height: 15px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content:space-between;
+}
+.playlistToggle div {
+ width: 100%;
+ height: 2px;
+ border-bottom: 1px solid #999;
+ background: white;
+}
+section {
+ -webkit-overflow-scrolling: touch;
+ overflow-y: auto;
+ max-height: calc(100vh - 140px);
+ max-width: 500px;
+ background: black;
+ position: absolute;
+ bottom: 160px; left: 0;
+ margin: 10px 10px;
+ padding: 10px;
+ background: rgba(20,5,10,0.5);
+ pointer-events: none;
+ opacity: 0;
+ transition: opacity 200ms;
+}
+.bio #bio,
+.discography #discography,
+.hardware #hardware,
+.contact #contact {
+ opacity: 1;
+ pointer-events: auto;
+}
+@keyframes fade {
+ 0% { opacity: 0.6; }
+ 50% { opacity: 1.0; }
+ 90% { opacity: 0.7; }
+100% { opacity: 0.6; }
+}
+
+@media (max-width: 700px) {
+ * { box-sizing: border-box; }
+ header {
+ bottom: auto;
+ top: 0px;
+ }
+ header .row {
+ flex-direction: column;
+ }
+ header .row .menu {
+ flex-direction: row;
+ flex-wrap: wrap;
+ }
+ h1 {
+ flex: 1 1 100%;
+ text-align: center;
+ }
+ .menu a {
+ display: block;
+ text-align: center;
+ margin-left: 6px;
+ margin-right: 6px;
+ padding-bottom: 10px;
+ }
+ .menu a.active {
+ border: 0;
+ }
+ .playlist {
+ width: 100vw;
+ margin: 0;
+ bottom: 59px;
+ }
+ section {
+ height: calc(100vh - 150px);
+ width: 100%;
+ max-width: auto;
+ min-width: auto;
+ max-height: auto;
+ padding-bottom: 20px;
+ bottom: auto;
+ top: 90px;
+ margin: 0;
+ }
+ .player {
+ position: fixed;
+ bottom: 0;
+ background: rgba(80,10,60,0.6);
+ width: 100vw;
+ padding: 12px 20px;
+ }
+ .playlistToggle {
+ width: 36px;
+ height: 36px;
+ }
+} \ No newline at end of file
diff --git a/docs/assets/fonts/NHaasGroteskTXPro-55Rg.ttf b/docs/assets/fonts/NHaasGroteskTXPro-55Rg.ttf
new file mode 100755
index 0000000..e5ad72b
--- /dev/null
+++ b/docs/assets/fonts/NHaasGroteskTXPro-55Rg.ttf
Binary files differ
diff --git a/docs/assets/fonts/NHaasGroteskTXPro-56It.ttf b/docs/assets/fonts/NHaasGroteskTXPro-56It.ttf
new file mode 100755
index 0000000..8aa3443
--- /dev/null
+++ b/docs/assets/fonts/NHaasGroteskTXPro-56It.ttf
Binary files differ
diff --git a/docs/assets/fonts/NHaasGroteskTXPro-75Bd.ttf b/docs/assets/fonts/NHaasGroteskTXPro-75Bd.ttf
new file mode 100755
index 0000000..d80c0ee
--- /dev/null
+++ b/docs/assets/fonts/NHaasGroteskTXPro-75Bd.ttf
Binary files differ
diff --git a/docs/assets/fonts/NHaasGroteskTXPro-76BdIt.ttf b/docs/assets/fonts/NHaasGroteskTXPro-76BdIt.ttf
new file mode 100755
index 0000000..81dfad5
--- /dev/null
+++ b/docs/assets/fonts/NHaasGroteskTXPro-76BdIt.ttf
Binary files differ
diff --git a/docs/assets/fonts/alarmclock.ttf b/docs/assets/fonts/alarmclock.ttf
new file mode 100755
index 0000000..9e9b593
--- /dev/null
+++ b/docs/assets/fonts/alarmclock.ttf
Binary files differ
diff --git a/docs/assets/fonts/roadrage.ttf b/docs/assets/fonts/roadrage.ttf
new file mode 100755
index 0000000..a7699af
--- /dev/null
+++ b/docs/assets/fonts/roadrage.ttf
Binary files differ
diff --git a/docs/assets/img/dreaming-city.jpg b/docs/assets/img/dreaming-city.jpg
new file mode 100644
index 0000000..211a0a9
--- /dev/null
+++ b/docs/assets/img/dreaming-city.jpg
Binary files differ
diff --git a/docs/assets/img/escape-from-neukoelln.jpg b/docs/assets/img/escape-from-neukoelln.jpg
new file mode 100644
index 0000000..dcd1180
--- /dev/null
+++ b/docs/assets/img/escape-from-neukoelln.jpg
Binary files differ
diff --git a/docs/assets/img/pause-button.png b/docs/assets/img/pause-button.png
new file mode 100644
index 0000000..6ab7818
--- /dev/null
+++ b/docs/assets/img/pause-button.png
Binary files differ
diff --git a/docs/assets/img/pause-inv.png b/docs/assets/img/pause-inv.png
new file mode 100644
index 0000000..9780255
--- /dev/null
+++ b/docs/assets/img/pause-inv.png
Binary files differ
diff --git a/docs/assets/img/pause.png b/docs/assets/img/pause.png
new file mode 100644
index 0000000..c2d30ae
--- /dev/null
+++ b/docs/assets/img/pause.png
Binary files differ
diff --git a/docs/assets/img/play-button.png b/docs/assets/img/play-button.png
new file mode 100644
index 0000000..c0fd3fc
--- /dev/null
+++ b/docs/assets/img/play-button.png
Binary files differ
diff --git a/docs/assets/img/play-fill.png b/docs/assets/img/play-fill.png
new file mode 100644
index 0000000..2205696
--- /dev/null
+++ b/docs/assets/img/play-fill.png
Binary files differ
diff --git a/docs/assets/img/play-inv.png b/docs/assets/img/play-inv.png
new file mode 100644
index 0000000..4baaa5f
--- /dev/null
+++ b/docs/assets/img/play-inv.png
Binary files differ
diff --git a/docs/assets/img/play.png b/docs/assets/img/play.png
new file mode 100644
index 0000000..b5b4a08
--- /dev/null
+++ b/docs/assets/img/play.png
Binary files differ
diff --git a/docs/assets/img/playbutton.psd b/docs/assets/img/playbutton.psd
new file mode 100644
index 0000000..e2dbed4
--- /dev/null
+++ b/docs/assets/img/playbutton.psd
Binary files differ
diff --git a/docs/assets/img/xena-vectra-logo-sm.png b/docs/assets/img/xena-vectra-logo-sm.png
new file mode 100644
index 0000000..b42111b
--- /dev/null
+++ b/docs/assets/img/xena-vectra-logo-sm.png
Binary files differ
diff --git a/docs/assets/img/xena-vectra-logo.png b/docs/assets/img/xena-vectra-logo.png
new file mode 100644
index 0000000..4b3f810
--- /dev/null
+++ b/docs/assets/img/xena-vectra-logo.png
Binary files differ
diff --git a/docs/assets/img/xenavectra.gif b/docs/assets/img/xenavectra.gif
new file mode 100644
index 0000000..fb81d57
--- /dev/null
+++ b/docs/assets/img/xenavectra.gif
Binary files differ
diff --git a/docs/assets/js/cielab.js b/docs/assets/js/cielab.js
new file mode 100644
index 0000000..14c096f
--- /dev/null
+++ b/docs/assets/js/cielab.js
@@ -0,0 +1,70 @@
+var cielab = (function(){
+ var cielab = {}
+
+ var xyz = [0,0,0]
+ var rgb = [0,0,0]
+
+ L_range = [0, 100]
+ a_range = [-86.185, 98.254]
+ b_range = [-107.863, 94.482]
+
+ cielab.gradient = function (n) {
+ n = n || 100
+ var k = 0
+
+ var L, a, b
+
+ var L0 = randrange(L_range[0] + 50, L_range[1])
+ var L1 = randrange(L_range[0]+ 50, L_range[1])
+ var a0 = randrange(a_range[0], a_range[1])
+ var a1 = randrange(a_range[0], a_range[1])
+ var b0 = randrange(b_range[0], b_range[1])
+ var b1 = randrange(b_range[0], b_range[1])
+ return function next (aa){
+ L = mix(k/n, L0, L1)
+ a = mix(k/n, a0, a1)
+ b = mix(k/n, b0, b1)
+ rgb = xyz2rgb(hunterlab2xyz(L, a, b))
+ k += 1
+ return rgba_string(rgb, aa)
+ }
+ }
+ function rgba_string (rgb, a) { return "rgba(" + rgb.map(Math.round).join(",") + "," + a + ")" }
+ function hex_string (rgb) { return "#" + rgb.map(Math.round).map(function(n){ var s = n.toString(16); return s.length == 1 ? "0"+s : s }).join("") }
+
+ function mix(n,a,b){ return n*a + (1-n)*b }
+ function clamp(n,a,b){ return n<a?a:n<b?n:b }
+ function hunterlab2xyz (L,a,b) {
+ var_Y = L / 10
+ var_X = a / 17.5 * L / 10
+ var_Z = b / 7 * L / 10
+
+ Y = Math.pow(var_Y, 2)
+ X = ( var_X + Y ) / 1.02
+ Z = -( var_Z - Y ) / 0.847
+ xyz = [X,Y,Z]
+ }
+ function xyz2rgb(){
+ var var_X = xyz[0] / 100 //X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
+ var var_Y = xyz[1] / 100 //Y from 0 to 100.000
+ var var_Z = xyz[2] / 100 //Z from 0 to 108.883
+
+ var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986
+ var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415
+ var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570
+
+ if ( var_R > 0.0031308 ) var_R = 1.055 * Math.pow( var_R, 1 / 2.4 ) - 0.055
+ else var_R = 12.92 * var_R
+ if ( var_G > 0.0031308 ) var_G = 1.055 * Math.pow( var_G, 1 / 2.4 ) - 0.055
+ else var_G = 12.92 * var_G
+ if ( var_B > 0.0031308 ) var_B = 1.055 * Math.pow( var_B, 1 / 2.4 ) - 0.055
+ else var_B = 12.92 * var_B
+
+ rgb[0] = clamp(var_R * 255, 0, 255)
+ rgb[1] = clamp(var_G * 255, 0, 255)
+ rgb[2] = clamp(var_B * 255, 0, 255)
+ return rgb
+ }
+
+ return cielab
+})() \ No newline at end of file
diff --git a/docs/assets/js/player.js b/docs/assets/js/player.js
new file mode 100644
index 0000000..25fdfd6
--- /dev/null
+++ b/docs/assets/js/player.js
@@ -0,0 +1,79 @@
+const player = (function(){
+ let player = {}
+ let current_index = -1
+ let audio = document.createElement('audio')
+ let tracks = [
+ { file: "mp3/xena_vectra-cruise.mp3", title: "Cruise" },
+ { file: "mp3/xena_vectra-dreaming_city_2.mp3", title: "Dreaming City 2" },
+ { file: "mp3/xena_vectra-escape_from_nk.mp3", title: "Escape from Neukölln" },
+ ]
+ function init(){
+ bind()
+ build()
+ // play(0)
+ }
+ function bind(){
+ audio.addEventListener('play', handlePlay)
+ audio.addEventListener('pause', handlePause)
+ audio.addEventListener('ended', handleEnded)
+ document.querySelector('.player .icon').addEventListener('click', togglePlaying)
+ document.querySelector('.player .track').addEventListener('click', play)
+ document.querySelector('.player .playlistToggle').addEventListener('click', togglePlaylist)
+ }
+ function build() {
+ tracks.forEach((track, i) => {
+ let el = document.createElement('li')
+ el.innerHTML = track.title
+ el.addEventListener('click', () => {
+ if (is_mobile) {
+ hidePlaylist()
+ }
+ shards.rebuild()
+ play(i)
+ })
+ document.querySelector('.playlist ul').appendChild(el)
+ })
+ document.querySelector('.player .track').innerHTML = tracks[0].title
+ }
+ function play(n){
+ const active = document.querySelector('.playlist ul .active')
+ if (active) active.classList.remove('active')
+ document.querySelector('.playlist ul').children[n].classList.add('active')
+
+ current_index = (n + tracks.length) % tracks.length
+ audio.src = tracks[n].file
+ audio.play()
+ document.querySelector('.player .track').innerHTML = tracks[n].title
+ }
+ function handlePlay(){
+ document.querySelector('.player').classList.add('playing')
+ document.querySelector('.player').classList.remove('paused')
+ shards.step()
+ }
+ function handlePause(){
+ document.querySelector('.player').classList.remove('playing')
+ document.querySelector('.player').classList.add('paused')
+ }
+ function handleEnded(){
+ shards.rebuild()
+ play(current_index+1)
+ }
+ function togglePlaying() {
+ // sounds.play('click')
+ if (current_index == -1) {
+ play(0)
+ } else {
+ if (audio.paused) audio.play()
+ else audio.pause()
+ }
+ }
+ function togglePlaylist() {
+ site.navigateHash('')
+ document.querySelector('.playlist').classList.toggle('visible')
+ }
+ function hidePlaylist() {
+ document.querySelector('.playlist').classList.remove('visible')
+ }
+ init()
+ return { hidePlaylist }
+})() \ No newline at end of file
diff --git a/docs/assets/js/shards.js b/docs/assets/js/shards.js
new file mode 100644
index 0000000..1b374ee
--- /dev/null
+++ b/docs/assets/js/shards.js
@@ -0,0 +1,107 @@
+const shards = (function(){
+ let count
+ let delay = 120 * 1000
+ let els = []
+ let t = 0
+ let rebuilding = false
+ let nextTimeout
+ let dark, light
+ const bg_el = document.querySelector('.bgs')
+
+ function init(){
+ bind()
+ build()
+ step()
+ setTimeout(next, 20)
+ bg_el.classList.remove('fade')
+ }
+ function bind(){
+ document.querySelector('h1').addEventListener('click', () => {
+ sounds.play('click')
+ rebuild()
+ site.navigateHash('')
+ player.hidePlaylist()
+ })
+ }
+ function build(){
+ count = choice(is_mobile ? [5,7] : [5,7,7,11,11])
+ light = cielab.gradient(count)
+ dark = cielab.gradient(count)
+ let el
+ for (var i = 0; i < count; i++) {
+ el = append(i)
+ }
+ }
+ function destroy(){
+ for (var i = 0; i < count; i++) {
+ els[i] && bg_el.removeChild(els[i])
+ }
+ els.length = 0
+ }
+ function rebuild(){
+ if (rebuilding) return
+ rebuilding = true
+ // sounds.play('click')
+ stars.rebuild()
+ next()
+ t = 0
+ bg_el.classList.add('fade')
+ setTimeout(() => {
+ destroy()
+ build()
+ step()
+ setTimeout(next, 20)
+ bg_el.classList.remove('fade')
+ rebuilding = false
+ // sounds.play('click')
+ }, 500)
+ }
+ function append(i){
+ const el = document.createElement('div')
+ el.classList.add('bg')
+ els.push(el)
+ bg_el.appendChild(el)
+ return el
+ }
+ function next(){
+ clearTimeout(nextTimeout)
+ nextTimeout = setTimeout(next, delay)
+ step()
+ }
+ function step() {
+ t += 1
+ light = cielab.gradient(count)
+ let w = { min: is_mobile ? randrange(40, 90) : randrange(20, 40), max: randrange(10, 90) }
+ if (w.min > w.max) {
+ w.min += 10
+ }
+ let rot = { min: randint(360), max: randrange(720, 1080) }
+ for (var i = 0; i < count; i++) {
+ update(i, t, w, rot, dark, light)
+ }
+ document.body.style.backgroundColor = cielab.gradient(2)(0.05)
+ }
+ function update(i, t, w, rot){
+ const el = els[i]
+ const n = i / count
+ const side = lerp(n, w.min, w.max)
+ const spin = lerp(i % 2 ? (1-n) : (n), rot.min, rot.max)
+ const rotation = "rotate3d(" + [randrange(-1,1), randrange(-1,1), randrange(-1,1)].join(',') + ',' + randint(360) + "deg)"
+ el.style.width = side + 'vmin'
+ el.style.height = side + 'vmin'
+ el.style.transform = "translate3d(-50%, -50%, 0) rotate(" + spin + "deg) translate3d(50%, 50%, 0) " + rotation
+ // el.style.transform = "translate3d(-50%, -50%, 0)"
+ if (t === 1) {
+ light = cielab.gradient(count)
+ if (is_mobile) {
+ el.style.backgroundImage = 'linear-gradient(0deg, ' + dark(1) + ', ' + light(1) + ')'
+ } else {
+ el.style.backgroundImage = 'linear-gradient(0deg, ' + dark(1) + ', ' + light(0) + ')'
+ }
+ }
+ el.style.backgroundColor = light(1)
+ el.style.opacity = lerp(n, randrange(0.1, 0.4), randrange(0.2, 0.5))
+ }
+ init()
+ return { rebuild: rebuild, step: step, }
+})() \ No newline at end of file
diff --git a/docs/assets/js/site.js b/docs/assets/js/site.js
new file mode 100644
index 0000000..bff06bb
--- /dev/null
+++ b/docs/assets/js/site.js
@@ -0,0 +1,72 @@
+const site = (function(){
+ let section
+ let links = toArray(document.querySelectorAll('.menu a'))
+ let time = new Date()
+ let hour = time.getHours()
+ let quotes = [
+ "So, are softsynths as nasty as they say?",
+ "Ah, a hardware person, I get it.",
+ "You have to make space to leave space.",
+ "Those waveforms are more powerful than we realize.",
+ "And that sub-oscillator? W-O-W!",
+ "Get in there, sweep the filter and give yourself a pat on the back. In that order.",
+ "Not a museum. Move along.",
+ "I've got to get out of this studio and back out there.",
+ ]
+ if (hour < 8 || hour > 16) {
+ document.body.parentNode.classList.add('night')
+ } else {
+ document.body.parentNode.classList.add('day')
+ }
+ preload('img/pause-inv.png')
+ setTimeout(() => {
+ document.body.classList.remove('loading')
+ navigateHash(window.location.hash)
+ const email = atob("eGVuYXZlY3RyYTkwOUBnbWFpbC5jb20=")
+ const twitter = atob("dmVjdHJheGVuYQ==")
+ document.querySelector("#email_addr").href = 'mailto:' + email
+ document.querySelector("#email_addr").innerHTML = email
+ document.querySelector("#twitter_addr").innerHTML = twitter
+ document.querySelector("#twitter_addr").href = 'https://twitter.com/' + twitter
+ }, 0)
+ toArray(document.querySelectorAll('.menu a')).forEach(a => {
+ a.addEventListener("click", e => {
+ e.preventDefault()
+ sounds.play('click')
+ console.log(e.target)
+ if (e.target.nodeName.toLowerCase() !== 'a') {
+ navigateHash(e.target.parentNode.href)
+ } else {
+ navigateHash(e.target.href)
+ }
+ })
+ })
+ function navigateHash(url){
+ if (is_mobile) {
+ player.hidePlaylist()
+ }
+ let new_section = (url || "").split('#')[1]
+ if (section) {
+ document.body.classList.remove(section)
+ links.forEach(link => link.classList.remove('active'))
+ }
+ if (new_section && new_section !== section) {
+ if (new_section.match('hardware')) {
+ document.querySelector('#quote').innerHTML = choice(quotes)
+ }
+ document.body.classList.add(new_section)
+ links.forEach(link => link.getAttribute('href').match(new_section) && link.classList.add('active'))
+ section = new_section
+ } else {
+ section = null
+ }
+ // window.location.hash = section || ""
+ }
+ function preload(src) {
+ const img = new Image
+ img.src = src
+ }
+ return {
+ navigateHash: navigateHash
+ }
+})()
diff --git a/docs/assets/js/sounds.js b/docs/assets/js/sounds.js
new file mode 100644
index 0000000..39f725d
--- /dev/null
+++ b/docs/assets/js/sounds.js
@@ -0,0 +1,17 @@
+const sounds = (function(){
+ let sounds = {}
+ let els = {}
+ sounds.add = (fn) => {
+ const el = document.createElement('audio')
+ el.src = 'sounds/' + fn + '.mp3'
+ els[fn] = el
+ }
+ sounds.play = (fn) => {
+ const el = els[fn]
+ el.currentTime = 0
+ el.volume = 0.8
+ el.play()
+ }
+ sounds.add('click')
+ return sounds
+})()
diff --git a/docs/assets/js/stars.js b/docs/assets/js/stars.js
new file mode 100644
index 0000000..0637473
--- /dev/null
+++ b/docs/assets/js/stars.js
@@ -0,0 +1,63 @@
+const stars = (function(){
+ var canvas = document.createElement("canvas"), ctx = canvas.getContext('2d')
+ var s = Math.sin, c = Math.cos
+ document.addEventListener("DOMContentLoaded", function(){
+ document.body.appendChild(canvas)
+ canvas.classList.add('stars')
+ canvas.style.width="100%"
+ canvas.style.height="100%"
+ canvas.style.position="fixed"
+ canvas.style.top="0px"
+ canvas.style.left="0px"
+ canvas.style.zIndex=-1
+ document.body.addEventListener("resize", build)
+ // document.body.parentNode.style.backgroundColor="black"
+ ctx.strokeStyle="white"
+ build()
+ })
+ function ri(n){ return Math.random() * n }
+ function rr(a,b){ return (b-a) * Math.random() + a }
+ function build(){
+ var w = canvas.width = window.innerWidth * window.devicePixelRatio
+ var h = canvas.height = window.innerHeight * window.devicePixelRatio
+ ctx.clearRect(0,0,w,h)
+ var n = Math.sqrt(w*h)|0
+ while (n--) {
+ var x = ri(w)
+ var y = ri(h)
+ var r0 = rr(0, 1)
+ var r1 = rr(0, 1)
+ var r2 = rr(0, 1)
+ var t0 = ri(2*Math.PI)
+ var t1 = ri(2*Math.PI)
+ var t2 = ri(2*Math.PI)
+ var x0 = x+c(t0)*r0
+ var y0 = y+s(t0)*r0
+ var x1 = x+c(t1)*r1
+ var y1 = y+s(t1)*r1
+ var x2 = x+c(t2)*r2
+ var y2 = y+s(t2)*r2
+ ctx.beginPath()
+ ctx.moveTo(x,y)
+ ctx.bezierCurveTo(x0,y0,x1,y1,x2,y2)
+ var color = rr(0, 255)|0
+ ctx.strokeStyle="rgb("+color+","+color+","+color+")"
+ ctx.stroke()
+ }
+ }
+ let rebuilding = false
+ function rebuild(){
+ if (rebuilding) return
+ rebuilding = true
+ canvas.classList.add('fade')
+ document.body.classList.add('fade')
+ setTimeout(() => {
+ // destroy()
+ build()
+ canvas.classList.remove('fade')
+ document.body.classList.remove('fade')
+ rebuilding = false
+ }, 500)
+ }
+ return { rebuild: rebuild }
+})() \ No newline at end of file
diff --git a/docs/assets/js/util.js b/docs/assets/js/util.js
new file mode 100644
index 0000000..e40db4a
--- /dev/null
+++ b/docs/assets/js/util.js
@@ -0,0 +1,139 @@
+const is_iphone = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))
+const is_ipad = (navigator.userAgent.match(/iPad/i))
+const is_android = (navigator.userAgent.match(/Android/i))
+const is_mobile = is_iphone || is_ipad || is_android
+const is_desktop = !is_mobile;
+document.body.parentNode.classList.add(is_desktop ? 'desktop' : 'mobile')
+
+function avg(a,b,n){ return (a*(n-1) + b)/n }
+function rand(n){ return Math.random()*n }
+function randint(n) { return ~~(Math.random()*n) }
+function randrange(a,b){ return a+rand(b-a) }
+function choice(a) { return a[randint(a.length)] }
+function clamp(n,a,b) { return a > n ? a : n > b ? b : n }
+function sign(n){ return n < 0 ? -1 : 1 }
+function mod(n,m){ return n-(m * Math.floor(n/m)) }
+function lerp(n,a,b){ return (b-a)*n+a }
+function quantize(m,n){ return n * ((m/n)|0) }
+
+function randgauss (obj, jog) {
+ var radius = Math.random() * jog
+ var angle = Math.random() * Math.PI * 2
+ obj.left += Math.sin(angle) * radius
+ obj.top += Math.cos(angle) * radius
+}
+
+function shuffle(a){
+ for (var i = a.length; i > 0; i--){
+ var r = randint(i)
+ var swap = a[i-1]
+ a[i-1] = a[r]
+ a[r] = swap
+ }
+ return a
+}
+
+function toArray (els){
+ return Array.prototype.slice.apply(els)
+}
+
+// easing functions
+function circular (t) { return Math.sqrt( 1 - ( --t * t ) ) }
+function quadratic (t) { return t * ( 2 - t ) }
+function back (t) {
+ var b = 4;
+ return ( t = t - 1 ) * t * ( ( b + 1 ) * t + b ) + 1;
+}
+function bounce (t) {
+ if (t >= 1) return 1;
+ if ( ( t /= 1 ) < ( 1 / 2.75 ) ) {
+ return 7.5625 * t * t;
+ } else if ( t < ( 2 / 2.75 ) ) {
+ return 7.5625 * ( t -= ( 1.5 / 2.75 ) ) * t + 0.75;
+ } else if ( t < ( 2.5 / 2.75 ) ) {
+ return 7.5625 * ( t -= ( 2.25 / 2.75 ) ) * t + 0.9375;
+ } else {
+ return 7.5625 * ( t -= ( 2.625 / 2.75 ) ) * t + 0.984375;
+ }
+}
+function elastic (t) {
+ var f = 0.22,
+ e = 0.4;
+
+ if ( t === 0 ) { return 0; }
+ if ( t == 1 ) { return 1; }
+
+ return ( e * Math.pow( 2, - 10 * t ) * Math.sin( ( t - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
+}
+
+function preload (url) {
+ var img = new Image ()
+ var loaded = false, _cb
+ img.onload = function(){
+ if (loaded) return
+ loaded = true
+ if (_cb) { _cb(img) }
+ }
+ img.src = url
+ if (img.complete) { img.onload() }
+ return {
+ then: function(cb){
+ if (loaded) { cb(img) }
+ else { _cb = cb }
+ }
+ }
+}
+
+function preloadImages () {
+ var images = toArray(document.getElementById("images").children)
+ var count = 0, ready = false, _cb
+ images.forEach(function(img){
+ var loaded = false
+ img.onload = function(){
+ if (loaded) return
+ loaded = true
+ done(img)
+ }
+ if (img.complete) { img.onload() }
+ })
+ function done () {
+ if (++count == images.length && ! ready) {
+ ready = true
+ _cb && _cb()
+ }
+ }
+ return {
+ then: function(cb){
+ if (ready) { cb() }
+ else { _cb = cb }
+ }
+ }
+}
+
+function smoothstep(min,max,n){
+ var t = clamp((n - min) / (max - min), 0.0, 1.0);
+ return t * t * (3.0 - 2.0 * t)
+}
+
+function detrand (x,y) {
+ return (Math.sin( x * 12.9898 + y * 78.233 ) * 43758.5453) % 1
+}
+
+function gray_to_transparency(img) {
+ var canvas = document.createElement("canvas")
+ var ctx = canvas.getContext('2d')
+ var nw = img.naturalWidth, nh = img.naturalHeight
+ canvas.width = nw
+ canvas.height = nh
+ ctx.drawImage(img,0,0)
+ var pixels = ctx.getImageData(0,0,nw,nh)
+ var data = pixels.data
+ for (var i = 0, len = nw*nh*4; i < len; i += 4) {
+ data[i+3] = data[i]
+ data[i] = data[i+1] = data[i+2] = 255
+ }
+ ctx.putImageData(pixels,0,0)
+ return canvas
+}
+
+var TWO_PI = 2*Math.PI \ No newline at end of file
diff --git a/docs/assets/sounds/click.mp3 b/docs/assets/sounds/click.mp3
new file mode 100644
index 0000000..37e7df0
--- /dev/null
+++ b/docs/assets/sounds/click.mp3
Binary files differ
diff --git a/docs/assets/sounds/click.wav b/docs/assets/sounds/click.wav
new file mode 100644
index 0000000..7c45aed
--- /dev/null
+++ b/docs/assets/sounds/click.wav
Binary files differ