Published
Edited
Feb 21, 2022
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// from https://observablehq.com/@observablehq/animation-loops
{
const context = DOM.context2d(width, height);
let frame;
let frame_counter = 0;

d3.select(context.canvas).on('click', function(event) {
console.log('y');
flowers.push(new Flower(event.offsetX, event.offsetY));;
});
(function tick() {
console.log('y');
let tmp = new Uint8Array(bufferLength);
if (use_audio) analyser.getByteFrequencyData(tmp);
let aud_sum = 0;
for (let i of tmp) aud_sum += i;
console.log(aud_sum);
context.clearRect(0, 0, width, height);
for (let f of flowers) {
f.grow();
draw_flower(f, context, aud_sum, frame_counter);
}
frame_counter += 1;
console.log(frame_counter);
frame = requestAnimationFrame(tick);
})();
invalidation.then(() => cancelAnimationFrame(frame));
return context.canvas;
}
Insert cell
// I originally was doing this with a method but changing the rotation wouldn't work that way...
// some deal with methods being defined when I construct the object and then not responding to changes
// to global variables (not sure if that's an observable thing or a js thing...)
draw_flower = function(flower, ctx, audio_boost, fc) {
for (let i=0; i<flower.numPetals; i++) {
draw_petal(flower, ctx, i, fc);
}
//console.log(Math.log(audio_boost/300));
ctx.beginPath();
ctx.arc(flower.x, flower.y, flower.central_part_r*Math.max(1, Math.log(audio_boost/300)), 0, Math.PI * 2);
ctx.fillStyle = flower.central_color;
ctx.fill();
}

Insert cell
draw_petal = function(flower, ctx, petal_num, fc) {
//probably shouldn't calculate this every time...
let angle = (petal_num/flower.numPetals)*2*Math.PI;
let petal_angle = angle;
if (rotate_petals == 'Yes') {
angle = (petal_num/flower.numPetals+fc/360)*2*Math.PI;
petal_angle = angle;
} else if (rotate_petals == 'Buggy'){
angle = (petal_num/flower.numPetals+fc/360)*2*Math.PI;
}
let x = flower.x+Math.cos(angle)*flower.outer_part_r;
let y = flower.y+Math.sin(angle)*flower.outer_part_r;
ctx.beginPath();
ctx.ellipse(x, y, flower.outer_part_r, flower.outer_part_r*(2/5), petal_angle, 0, Math.PI * 2);
ctx.fillStyle = flower.petal_colors[petal_num%2];
ctx.fill();
}
Insert cell
class Flower {
constructor(x, y) {
this.x = x;
this.y = y;
this.r = 0;
this.central_part_r = 0;
this.central_color = center_colors[Math.floor(Math.random()*center_colors.length)];
this.petal_colors = [petal_colors[Math.floor(Math.random()*petal_colors.length)], petal_colors[Math.floor(Math.random()*petal_colors.length)]];
this.numPetals = 5 + Math.floor(Math.random()*7);
console.log(this.central_color);
}

grow() {
this.r += 1;
this.central_part_r = Math.min(this.r, 20);
this.outer_part_r = Math.min(this.r/2, 40);
}
/*
draw_it(ctx, audio_boost, fc) {
for (let i=0; i<this.numPetals; i++) {
this.draw_petal(ctx, i, fc);
}
//console.log(Math.log(audio_boost/300));
ctx.beginPath();
ctx.arc(this.x, this.y, this.central_part_r*Math.max(1, Math.log(audio_boost/300)), 0, Math.PI * 2);
ctx.fillStyle = this.central_color;
ctx.fill();
}

draw_petal(ctx, petal_num, fc) {
//probably shouldn't calculate this every time...
let x, y;
if (rotate_petals) {
x = this.x+Math.cos((petal_num/this.numPetals+fc/360)*2*Math.PI)*this.outer_part_r;
y = this.y+Math.sin((petal_num/this.numPetals+fc/360)*2*Math.PI)*this.outer_part_r;
} else {
x = this.x+Math.cos((petal_num/this.numPetals)*2*Math.PI)*this.outer_part_r;
y = this.y+Math.sin((petal_num/this.numPetals)*2*Math.PI)*this.outer_part_r;
}
ctx.beginPath();
ctx.ellipse(x, y, this.outer_part_r, this.outer_part_r*(2/5), (petal_num/this.numPetals)*2*Math.PI, 0, Math.PI * 2);
ctx.fillStyle = this.petal_colors[petal_num%2];
ctx.fill();
}
*/
}
Insert cell
Insert cell
Insert cell
Insert cell
audioCtx = new AudioContext()
Insert cell
stream = navigator.mediaDevices.getUserMedia({ audio: true })
Insert cell
analyser = {
var source = audioCtx.createMediaStreamSource(stream)
var analyser = audioCtx.createAnalyser()
analyser.fftSize = 2048
analyser.smoothingTimeConstant = 0.7 // default 0.8
source.connect(analyser)
return analyser
}
Insert cell
bufferLength = analyser.frequencyBinCount
Insert cell
petal_colors = ["#b7094c","#a01a58","#892b64","#723c70","#5c4d7d","#455e89","#2e6f95","#1780a1","#0091ad"];
Insert cell
center_colors = ["#627264","#a1cda8","#b5dfca","#c5e7e2","#ad9baa"];
Insert cell
d3 = require('d3')
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