Public
Edited
Feb 1
Insert cell
Insert cell
{
const size = 400;
const position = (x) => cm.map(x, 0, size);
const angle = (x) => cm.map(x, 0, 360);
const urls = [
await FileAttachment("blip.wav").url(),
await FileAttachment("pink.wav").url(),
await FileAttachment("takerimba.wav").url(),
await FileAttachment("tears.wav").url()
];
const players = urls.map((url) => {
const sound = new Tone.Player(url).toDestination();
return useProgress(sound);
});

const [state, dispose] = cm
.flow()
.let(
"progress",
urls.map(() => 0)
)
.on("loop", (d) => {
for (let i = 0; i < urls.length; i++) {
d.progress[i] = players[i].progress();
}
d.progress = [...d.progress];
})
.on("keydown", (_, { key }) => {
if (key === "a") players[0].start();
else if (key === "s") players[1].start();
else if (key === "d") players[2].start();
else if (key === "f") players[3].start();
})
.join();

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

await Tone.loaded;

return svg.svg({ width: size, height: size }, [
svg.rect({ x: 0, y: 0, width: size, height: size, fill: "black" }),
svg.circle({
cx: cm.$(() => position(state.progress[0])),
cy: size / 3,
r: 50,
fill: "white"
}),
svg.circle({
cx: size / 2,
cy: cm.$(() => position(state.progress[1])),
r: 50,
fill: "white"
}),
svg.g(
{
transform: cm.$(() =>
[
`translate(${size / 2}, ${size / 2}) `,
`rotate(${angle(state.progress[2])})`
].join()
)
},
[
svg.rect({
width: 100,
height: 100,
fill: "white"
})
]
)
]);
}
Insert cell
function useProgress(player) {
let startTime;

const start = (...params) => {
startTime = params[0] ?? Tone.now();
player.start(...params);
};

const progress = () => {
if (player.state !== "started") return 0;
const currentTime = Tone.now() - startTime;
return currentTime / player._buffer.duration;
};

return { start, progress };
}
Insert cell
svg = cm.svg
Insert cell
import { cm } from "@charming-art/charmingjs-next"
Insert cell
Tone = require("tone")
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