summaryrefslogtreecommitdiff
path: root/client/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/index.js')
-rw-r--r--client/index.js355
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();
-}