Public
Edited
Mar 11
Fork of Pitch Helix
Insert cell
Insert cell
{
const synth = new Tone.Synth();
synth.toDestination();

const data = [
() => synth.triggerAttack(440),
() => synth.triggerAttack(d3.randomUniform(100, 10000)()), // play a random frequency
() => synth.triggerAttack(d3.randomUniform(440, 880)()), // play a random frequency within an octave
() => synth.triggerAttack(d3.randomUniform(329.63, 349.23)()), // play a random frequency within an equal-tempered semitone
() => {
// play a random frequency within a 5-note scale that I made up
const myScale = [200.32, 350.55, 480, 670, 800];
const pos = Math.floor(d3.randomUniform(0, myScale.length)());
const frequency = myScale[pos];
synth.triggerAttack(frequency);
},
() => {
// play frequencies from a pentatonic scale
const pentatonic = [200, 225, 266.6666666666667, 300, 337.5, 400];
const pos = Math.floor(d3.randomUniform(0, pentatonic.length)());
const frequency = pentatonic[pos];
synth.triggerAttack(frequency);
}
];

function onMouseup() {
synth.triggerRelease();
}

const size = 50;
const padding = 10;
const width = data.length * (size + padding) + padding;
const height = size + padding * 2;

const app = cm.render({
width,
height,
draw: [
cm.svg("circle", data, {
cx: (_, i) => i * (size + padding) + size / 2,
cy: padding + size / 2,
r: size / 2,
fill: "black",
onMouseup,
onMousedown: (_, d) => d()
})
]
});

invalidation.then(() => app.dispose());

return app.node();
}
Insert cell
function mouseof(event) {
const rect = event.target.getBoundingClientRect();
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
return [mouseX, mouseY];
}
Insert cell
Tone = require("tone")
Insert cell
cm = require("charmingjs@0.0.13")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more