This repository has no description
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <title>Shapemaker Web</title>
7 <script type="module">
8 import init, {
9 render_image,
10 LayerWeb,
11 render_canvas,
12 Color,
13 color_name,
14 set_palette,
15 random_linelikes,
16 Filter,
17 ColorMapping,
18 random_color,
19 render_canvas_at,
20 } from "./shapemaker.js"
21 async function run() {
22 await init()
23 window.renderImage = (vel, col) => {
24 document
25 .querySelectorAll(`.frame[data-color=${color_name(col)}]`)
26 ?.forEach((el) => fadeOutElement(el, 200))
27 render_image(vel, col)
28 }
29
30 set_palette(
31 ColorMapping.from_css(`
32 :root {
33 black: #000000;
34 white: #ffffff;
35 red: #cf0a2b;
36 green: #22e753;
37 blue: #2734e6;
38 yellow: #f8e21e;
39 orange: #f05811;
40 purple: #6a24ec;
41 brown: #a05634;
42 pink: #e92e76;
43 gray: #81a0a8;
44 cyan: #4fecec;
45 }
46 `)
47 )
48 }
49 run()
50
51 function randomColor() {
52 const colors = [Color.Cyan, Color.Pink]
53 const random = Math.floor(Math.random() * colors.length)
54 return colors[random]
55 }
56
57 function fadeOutElement(el, durationOverride = null) {
58 if (!el) return
59 const duration = durationOverride ?? (window.pedal_held ? 5e3 : 200)
60 el.style.transition = `opacity ${duration}ms ease-out`
61 el.style.opacity = 0
62 setTimeout(() => el.remove(), duration)
63 }
64
65 function frameElement(color) {
66 return document.querySelector(`.frame[data-color=${color_name(color)}]`)
67 }
68
69 window.pedal_held = false
70 window.previousColor = null
71 window.numberOfFrames = 0
72
73 window.addEventListener("keypress", (e) => {
74 if (e.key === " ") {
75 const layer = random_linelikes(`feur${window.numberOfFrames++}`)
76 let color = randomColor()
77 window.previousColor = color
78 layer.paint_all(color, 1, Filter.glow(7))
79 render_canvas_at("body")
80 }
81 })
82
83 console.log("requesting midi access")
84 navigator.requestMIDIAccess().then((midiAccess) => {
85 Array.from(midiAccess.inputs).forEach((input) => {
86 input[1].onmidimessage = (msg) => {
87 const [cmd, ...args] = [...msg.data]
88 if (cmd === 248) return
89 console.log(cmd, args)
90 if (cmd === 176 && args[0] === 64) {
91 const [_, intensity] = args
92 window.pedal_held = intensity > 0
93 if (intensity === 0) {
94 document.querySelectorAll(".frame")?.forEach(fadeOutElement)
95 }
96 return
97 }
98 if (cmd !== 144) return
99 const [pitch, velocity] = args
100
101 const colors = [
102 Color.Blue,
103 Color.Purple,
104 Color.Pink,
105 Color.Red,
106 Color.Orange,
107 Color.Yellow,
108 Color.Green,
109 Color.Cyan,
110 ]
111
112 // get octave from pitch
113 const octave = Math.floor(pitch / 12) - 1
114
115 // if octave is 0, use the first color
116 const color = colors[octave] ?? colors[0]
117
118 if (velocity === 0) {
119 fadeOutElement(frameElement(color))
120 } else {
121 window.renderImage(velocity / 128, color ?? "white")
122 }
123 }
124 })
125 })
126 </script>
127 <style>
128 body {
129 background: #000;
130 }
131
132 .frame {
133 position: fixed;
134 top: 0;
135 left: 0;
136 right: 0;
137 bottom: 0;
138 display: flex;
139 justify-content: center;
140 align-items: center;
141 }
142 </style>
143 </head>
144 <body>
145 <div class="prev"></div>
146 </body>
147</html>