xxxxxxxxxx
214
const scale = new teoria.note("A3").scale("major");
let activeShape = "triangle";
let c = null;
let activeChordRoot = 1;
const walkers = [];
const waveTypes = {
circle: "sine",
square: "square",
triangle: "triangle",
sawtooth: "sawtooth",
};
const OUTPUT_NODE = new Tone.Gain(0.3);
const outputLimiter = new Tone.Limiter(-1);
const outputFilter = new Tone.Filter({
type: "lowpass",
frequency: 15000
});
const outputReverb = new Tone.Reverb({
wet: 0.2
});
OUTPUT_NODE.chain(outputFilter, outputReverb, outputLimiter, Tone.Master);
function Walker(startX, startY, type) {
let x = startX;
let y = startY;
const detune = random(-20, 20);
const synth = new Tone.Synth({
volume: type === "square" ? -30 : -20,
portamento: 0.1,
envelope: {
attack: 1,
decay: 15,
sustain: 0.5,
release: 1,
},
oscillator: {
detune,
type: waveTypes[type],
},
});
const panner = new Tone.Panner(map(x, 0, width, -1, 1));
const filter = new Tone.Filter({
type: "lowpass",
Q: 20,
frequency: 15000
});
const limiter = new Tone.Limiter(-20);
synth.chain(filter, limiter, panner, OUTPUT_NODE);
const noteOptions = [-7, 0, 2, 4, 6];
const getNote = () =>
activeChordRoot + noteOptions[Math.floor(random(0, noteOptions.length))];
let startingNote = getNote();
synth.triggerAttack(scale.get(startingNote).toString());
this.updateNote = () => {
setTimeout(() => {
startingNote = getNote();
synth.triggerAttack(scale.get(startingNote).toString());
}, random(0, 1000));
};
this.update = () => {
const positionNoise = noise(x / 100, y / 100);
const filterFreqPow = map(positionNoise, 0, 1, 6, 14)
filter.Q.rampTo(map(positionNoise, 0, 1, 0, 30), 0.1);
filter.frequency.rampTo(Math.pow(2, filterFreqPow), 0.2);
panner.pan.rampTo(map(x, 0, width, -1, 1), 0.4);
let hue = positionNoise * 360 + activeChordRoot * 80;
hue = hue % 360;
const frameNoise = noise(frameCount / 50);
colorMode(HSL);
rectMode(CENTER);
noStroke();
let w = frameNoise * 70 + 30;
let a = 0.03;
const r = floor(random(4));
const r2 = floor(random(100));
/* Sometimes draw bigger shapes */
if (r2 < 15) {
w = random(100, 200);
a = 0.01;
}
if (r2 < 5) {
w = random(200, 400);
a = 0.01;
}
if (r2 < 2) {
w = random(400, 800);
a = 0.01;
}
if (type === "circle") {
fill(hue, random(45), frameNoise * 10 + 50, a);
ellipse(x, y, w, w);
}
if (type === "square") {
fill(hue, 20, frameNoise * 3 + 50, a);
rect(x, y, w, w);
}
if (type === "triangle") {
fill(hue, 30, frameNoise * 100, a);
push();
translate(x, y);
rotate((frameNoise / 50) * PI * 2);
beginShape();
vertex(0, w);
vertex(-w, -5);
vertex(w, 5);
endShape(CLOSE);
pop();
}
if (type === "sawtooth") {
fill(hue, 30, frameNoise * 10 + 50, a + 0.1);
push();
translate(x, y);
beginShape();
vertex(0, 0);
vertex(0, w);
vertex(25, w);
endShape(CLOSE);
pop();
}
const delta = 10;
switch (r) {
case 0:
x = x + delta;
break;
case 1:
x = x - delta;
break;
case 2:
y = y + delta;
break;
case 3:
y = y - delta;
break;
}
if (x > width) {
x = 0;
}
if (x < 0) {
x = width;
}
if (y > height) {
y = 0;
}
if (y < 0) {
y = height;
}
};
}
function setup() {
c = createCanvas(600, 600);
c.mouseClicked(function() {
walkers.push(new Walker(mouseX, mouseY, activeShape));
})
background(255);
frameRate(20);
}
function draw() {
background(0, 0.001);
walkers.forEach((walker) => {
walker.update();
});
}
function keyPressed() {
if (key === "1") {
activeShape = "circle";
}
if (key === "2") {
activeShape = "square";
}
if (key === "3") {
activeShape = "triangle";
}
if (key === "4") {
activeShape = "sawtooth";
}
if (key === "a") {
activeChordRoot = Math.floor(random(0, 7));
walkers.forEach((walker) => {
walker.updateNote();
});
}
}