xxxxxxxxxx
222
const PHI = (1 + Math.sqrt(5)) / 2;
let SIZE;
const FRAMES = 500;
function setup() {
SIZE = min(windowWidth, windowHeight)
createCanvas(windowWidth, windowHeight);
colorMode(RGB, 1);
angleMode(DEGREES);
}
let ctx_stack;
function preDraw() {
randomSeed(1);
background(0.5, 0.25, 1);
translate(width / 2, height / 2);
const s = 0.1;
scale(s);
strokeWeight(SIZE / 200 / s);
rotate(-0.5 * 360);
ctx_stack = [structuredClone(default_ctx)];
t(millis() / 1000 * 60 / FRAMES)
}
function draw() {
preDraw();
// t(mx);
grow(bud);
// bud();
ring_radius(0.5);
ring_count(15);
ring(my_blossom);
}
function my_blossom() {
bud_size(1/8);
bud();
petal_size(1);
petal();
ring_radius(0);
ring_count(10);
ring(my_petal);
bud_size(1/3);
bud();
bud_size(bud_size() * 0.5);
bud();
bud_size(bud_size() * 0.75);
bud();
bud_size(bud_size() * 0.75);
bud();
}
function my_petal() {
wave_offset(t);
petal_size(wave);
petal_color("red")
petal();
}
const default_ctx = {
i: 0,
f: 0,
t: 0,
ring: {
count: 5,
radius: 0,
},
bud: {
size: 1,
color: "yellow",
},
petal: {
size: 1,
color: "white",
},
wave: {
count: 1,
min: 0,
max: 1,
offset: 0,
},
bounce: {
count: 1,
min: 0,
max: 1,
offset: 0,
}
};
function ctx() {
return ctx_stack.at(-1);
}
function pushCtx() {
ctx_stack.push(structuredClone(ctx()));
}
function popCtx() {
ctx_stack.pop();
}
const t = (val) => ctx().t= getVal(val) ?? ctx().t
const i = (val) => ctx().i = getVal(val) ?? ctx().i;
const f = (val) => ctx().f = getVal(val) ?? ctx().f;
const ring_count = (val) => ctx().ring.count = getVal(val) ?? ctx().ring.count;
const ring_radius = (val) => ctx().ring.radius = getVal(val) ?? ctx().ring.radius;
const bud_size = (val) => ctx().bud.size = getVal(val) ?? ctx().bud.size;
const bud_color = (val) => ctx().bud.color = getVal(val) ?? ctx().bud.color;
const petal_size = (val) => ctx().petal.size = getVal(val) ?? ctx().petal.size;
const petal_color = (val) => ctx().petal.color = getVal(val) ?? ctx().petal.color;
const wave_count = (val) => ctx().wave.count = getVal(val) ?? ctx().wave.count;
const wave_min = (val) => ctx().wave.min = getVal(val) ?? ctx().wave.min;
const wave_max = (val) => ctx().wave.max = getVal(val) ?? ctx().wave.max;
const wave_range = (min, max) => [
ctx().wave.min = min ?? ctx().wave.min,
ctx().wave.max = max ?? ctx().wave.max
];
const wave_offset = (val) => ctx().wave.offset = getVal(val) ?? ctx().wave.offset;
const bounce_count = (val) => ctx().bounce.count = getVal(val) ?? ctx().bounce.count;
const bounce_min = (val) => ctx().bounce.min = getVal(val) ?? ctx().bounce.min;
const bounce_max = (val) => ctx().bounce.max = getVal(val) ?? ctx().bounce.max;
const bounce_range = (min, max) => [
ctx().bounce.min = min ?? ctx().bounce.min,
ctx().bounce.max = max ?? ctx().bounce.max
];
const bounce_offset = (val) => ctx().bounce.offset = getVal(val) ?? ctx().bounce.offset;
function getVal(val) {
if (typeof val === 'function')
return val();
return val;
}
function wave(val) {
const { wave: { count, min, max, offset } } = ctx();
return map(
-cos((val ?? (f() * count + offset)) * 360),
-1, 1,
min, max
);
}
function bounce() {
const { bounce: { count, min, max, offset } } = ctx();
return map(
1 - (abs(1 - fract(f() * count + offset) * 2)),
0, 1,
min, max
);
}
function grow() {
push();
pushCtx();
[arguments].map(f => f());
popCtx();
pop();
}
function ring(func) {
const { ring: { count, radius } } = ctx();
for (let _i=0; _i<count; _i++) {
const _f = _i/count;
grow(() => {
i(_i);
f(_f);
rotate(360 * (_f - 0.5))
translate(0, SIZE * radius);
func();
});
}
}
function petal() {
const { petal: { size, color }} = ctx();
fill(color);
translate(0, 0.5 * size * SIZE);
ellipse(
0,
0,
0.5 * size * SIZE,
size * SIZE
);
translate(0, 0.5 * size * SIZE);
}
function bud() {
const { bud: { size, color }} = ctx();
fill(color);
circle(0, 0, size * SIZE);
translate(0, 0.5 * size * SIZE);
}
function move(val) {
translate(0, val * SIZE);
}
function mx() {
return mouseX / width;
}
function my() {
return mouseY / height;
}