diff options
| author | julian laplace <julescarbon@gmail.com> | 2025-06-30 23:35:13 +0200 |
|---|---|---|
| committer | julian laplace <julescarbon@gmail.com> | 2025-06-30 23:35:13 +0200 |
| commit | e5ec8893d18aa21f771ab56fc5ded42602125f94 (patch) | |
| tree | f9b95619cfa86ff6ea72302defbee5367f2d3307 /client/index.js | |
| parent | dfcdf790e3879678d8b3a9b729cca03174b32d55 (diff) | |
fixes
Diffstat (limited to 'client/index.js')
| -rw-r--r-- | client/index.js | 355 |
1 files changed, 112 insertions, 243 deletions
diff --git a/client/index.js b/client/index.js index 87cf113..527d8db 100644 --- a/client/index.js +++ b/client/index.js @@ -3,18 +3,16 @@ import gcd from "compute-gcd"; import keys from "./lib/keys"; import color from "./lib/color"; import kalimba from "./lib/kalimba"; -import life from "./lib/life"; import organ from "./lib/organ"; import { browser, requestAudioContext, choice } from "./lib/util"; +import { PRIMES } from "./lib/primes"; +// import life from "./lib/life"; let instrument = kalimba; const root = 440; const s = 50; -const w = window.innerWidth; -const h = window.innerHeight; -const ws = Math.ceil(w / s), - hs = Math.ceil(h / s); +let w, h, ws, hs; const add_on = 0; const mul_on = 1.0; @@ -25,32 +23,57 @@ let dragging = false; let erasing = false; let lastFreq = 0; let notes = []; +let base_x = 0; +let base_y = 0; +let is_split = false; requestAudioContext(() => { + kalimba.load(); + build(); + bind(); +}); + +function build() { + w = window.innerWidth; + h = window.innerHeight; + ws = Math.ceil(w / s); + hs = Math.ceil(h / s); for (var i = 0; i < ws; i++) { notes[i] = []; for (var j = 0; j < hs; j++) { notes[i][j] = add(i, j); } } - life.init(notes, assign); -}); - +} +function rebuild() { + notes.forEach((row) => row.forEach((note) => note.destroy())); + build(); +} function play(freq) { - if (freq.playing) return; + if (instrument === organ && freq.playing) return; freq.playing = true; - instrument.play(freq.frequency); - if (instrument === organ || hash || life.isRunning()) { + let frequency = freq.frequency; + + // while (frequency < root) { + // frequency *= 2; + // } + // while (frequency > root) { + // frequency /= 2; + // } + + instrument.play(frequency); + if (instrument === organ || hash) { + // || life.isRunning()) { freq.div.classList.add("playing"); } - life.assign_item(freq, true); + // life.assign_item(freq, true); } function pause(freq) { if (!freq.playing) return; freq.playing = false; instrument.pause(freq.frequency); freq.div.classList.remove("playing"); - life.assign_item(freq, false); + // life.assign_item(freq, false); } function assign(freq, state) { if (state) { @@ -62,104 +85,17 @@ function assign(freq, state) { function toggle(freq) { assign(freq, !freq.playing); } -const gliderShape = [ - [0, 0, 0, 0, 0], - [0, 1, 1, 1, 0], - [0, 0, 0, 1, 0], - [0, 0, 1, 0, 0], - [0, 0, 0, 0, 0], -]; -const gliderShapeFlip = gliderShape.map((a) => a.slice(0).reverse()); -const gliderShapes = [ - gliderShape, - gliderShapeFlip, - gliderShape.slice(0).reverse(), - gliderShapeFlip.slice(0).reverse(), -]; -function glider() { - const x = Math.floor(Math.random() * ws); - const y = Math.floor(Math.random() * hs); - const shape = choice(gliderShapes); - weave(x, y, shape); -} -function weave(x, y, shape) { - const xmag = shape.length; - const ymag = shape[0].length; - let i, j, px, py; - for (i = 0; i < xmag; i++) { - for (j = 0; j < ymag; j++) { - px = (x + i) % ws; - py = (y + j) % hs; - assign(notes[px][py], shape[i][j]); - } - } -} -function forEach(f) { - let i, j, note, s; - for (i = 0; i < ws; i++) { - for (j = 0; j < hs; j++) { - note = notes[i][j]; - s = f(i, j, note.playing); - assign(note, s); - } - } -} -function clone() { - let i, j; - let a = []; - for (i = 0; i < ws; i++) { - a[i] = []; - for (j = 0; j < hs; j++) { - a[i][j] = notes[i][j].playing; - } - } - return a; -} -function move(dx, dy) { - let a = clone(); - forEach((x, y, state) => { - x = (x + dx + ws) % ws; - y = (y + dy + hs) % hs; - return a[x][y]; - }); -} -function clear() { - forEach(() => { - return false; - }); -} -function stripex(odd) { - odd = !!odd; - forEach((x) => { - return x % 2 ? odd : !odd; - }); -} -function stripey(odd) { - odd = !!odd; - forEach((x, y) => { - return y % 2 ? odd : !odd; - }); -} -function checker(odd, n) { - odd = !!odd; - n = n || 1; - forEach((x, y) => { - return Math.floor(x / n) % 2 ^ Math.floor(y / n) % 2 ? odd : !odd; - }); -} -function noise(n) { - n = n || 0.5; - n = n * n; - forEach(() => { - return Math.random() < n; - }); -} function add(i, j) { - const a = i + 1; - const b = j + 1; + const a = i + 1 + base_x; + const b = j + 1 + base_y; + // const a = i + 1; + // const b = i + j + 2; + // const a = PRIMES[i]; + // const b = PRIMES[i + j + 1]; const div = document.createElement("div"); const frequency = (root * a) / b; + // const frequency = root * Math.pow(2, ((b / a) % 1) + 1); let add = 0; let frac; div.style.left = i * s + "px"; @@ -171,6 +107,9 @@ function add(i, j) { i, j, playing: false, + destroy: () => { + div.parentNode.removeChild(div); + }, recolor: (numerator, denominator) => { let aa = a / numerator; let bb = b / denominator; @@ -215,20 +154,30 @@ function add(i, j) { if (event.button === 2) { // rightclick event.preventDefault(); - notes.forEach((row) => row.forEach((note) => note.recolor(a, b))); + // notes.forEach((row) => row.forEach((note) => note.recolor(a, b))); + is_split = [a, b]; return; } div.style.backgroundColor = color(frac, add + add_on, mul_on); - toggle(freq); - erasing = !freq.playing; + dragging = true; + if (instrument === organ) { + toggle(freq); + erasing = !freq.playing; + } else { + play(freq); + } }); div.addEventListener("mouseenter", function () { div.style.backgroundColor = color(frac, add + add_on, mul_on); if (dragging) { - if (erasing) { - pause(freq); + if (instrument === organ) { + if (erasing) { + pause(freq); + } else { + toggle(freq); + } } else { - toggle(freq); + play(freq); } } }); @@ -252,154 +201,81 @@ function add(i, j) { return freq; } -if (browser.isDesktop) { - document.addEventListener("mousedown", (event) => { - if (event.button !== 2) { +function bind() { + window.addEventListener("resize", build); + if (browser.isDesktop) { + document.addEventListener("mousedown", (event) => { + if (event.button !== 2) { + dragging = true; + } + }); + document.addEventListener("mouseup", () => { + dragging = false; + }); + } else { + document.addEventListener("touchstart", (e) => { + e.preventDefault(); dragging = true; - } - }); - document.addEventListener("mouseup", () => { - dragging = false; - }); -} else { - document.addEventListener("touchstart", (e) => { - e.preventDefault(); - dragging = true; - }); - document.addEventListener("touchmove", (e) => { - e.preventDefault(); - const x = Math.floor(e.touches[0].pageX / s); - const y = Math.floor(e.touches[0].pageY / s); - if (!(x in notes) || !(y in notes[x])) return; - const freq = notes[x][y]; - if (freq !== lastFreq) { - if (dragging) { - if (erasing) { - pause(freq); - } else { - toggle(freq); + }); + document.addEventListener("touchmove", (e) => { + e.preventDefault(); + const x = Math.floor(e.touches[0].pageX / s); + const y = Math.floor(e.touches[0].pageY / s); + if (!(x in notes) || !(y in notes[x])) return; + const freq = notes[x][y]; + if (freq !== lastFreq) { + if (dragging) { + if (erasing) { + pause(freq); + } else { + toggle(freq); + } } + lastFreq = freq; } - lastFreq = freq; - } - }); - document.addEventListener("touchend", () => { - dragging = false; - }); + }); + document.addEventListener("touchend", () => { + dragging = false; + }); + } } function swap_instrument() { instrument = instrument === kalimba ? organ : kalimba; } -let life_bpm = 50; window.addEventListener("keydown", keydown, true); function keydown(e) { // console.log(e.keyCode) if (e.altKey || e.ctrlKey || e.metaKey) return; switch (e.keyCode) { - case 32: // space - life.toggle(); - break; - case 188: // comma - life_bpm += e.shiftKey ? 1 : 5; - life.setTempo(life_bpm); - break; - case 190: // period - life_bpm -= e.shiftKey ? 1 : 5; - life_bpm = Math.max(1, life_bpm); - life.setTempo(life_bpm); - break; case 37: // left - move(1, 0); + base_x = Math.max(0, base_x - 1); + rebuild(); break; case 38: // up - move(0, 1); + base_y = Math.max(0, base_y - 1); + rebuild(); break; case 39: // right - move(-1, 0); + base_x += 1; + rebuild(); break; case 40: // down - move(0, -1); - break; - case 71: // g - glider(); - break; - case 83: // s - swap_instrument(); - break; - case 67: // c - clear(); - break; - case 87: // w - clear(); - break; - case 78: // n - noise(0.5); - break; - case 69: // e - stripex(Math.random() < 0.5); - break; - case 82: // r - stripey(Math.random() < 0.5); - break; - case 84: // t - checker(Math.random() < 0.5, 1); - break; - case 89: // y - checker(Math.random() < 0.5, 2); - break; - case 85: // u - checker(Math.random() < 0.5, 3); - break; - case 73: // i - checker(Math.random() < 0.5, 4); - break; - case 79: // o - checker(Math.random() < 0.5, 5); - break; - case 80: // p - checker(Math.random() < 0.5, 6); - break; - case 219: // [ - checker(Math.random() < 0.5, 7); - break; - case 221: // ] - checker(Math.random() < 0.5, 11); - break; - case 49: // 1 - noise(0.1); - break; - case 50: // 2 - noise(0.2); - break; - case 51: // 3 - noise(0.3); - break; - case 52: // 4 - noise(0.4); - break; - case 53: // 5 - noise(0.5); - break; - case 54: // 6 - noise(0.6); - break; - case 55: // 7 - noise(0.7); - break; - case 56: // 8 - noise(0.8); - break; - case 57: // 9 - noise(0.9); - break; - case 48: // 0 - noise(1); + base_y += 1; + rebuild(); break; } } keys.listen(function (index) { + index += 7; + const x = index % 7; + const y = Math.floor(index / 7); + const a = x; + const b = y + 1; + const freq = notes[a][b]; + console.log(a, b, freq.frequency); + play(freq); // const freq = scales.current().index(index) // document.body.style.backgroundColor = color( index / scales.current().scale.length ) // instrument.toggle(freq) @@ -409,10 +285,3 @@ let hash = window.location.hash || window.location.search; if (hash.match("sin") || hash.match("organ")) { instrument = organ; } -if (hash.match("glider")) { - instrument = organ; - clear(); - glider(); - life.setTempo((life_bpm = 120 * 8)); - life.toggle(); -} |
