ai generated solutions to our ai generated problems

This commit is contained in:
Heidi
2026-06-15 08:52:18 +01:00
parent efe233667f
commit 91a657522a
3 changed files with 156 additions and 73 deletions
+54 -16
View File
@@ -1,6 +1,6 @@
import React, { useEffect, useRef } from "react";
import { TRUNK_TOP_CSS } from "./Tree";
// this is a comment
interface Leaf {
x: number;
y: number;
@@ -23,24 +23,35 @@ export default function FallingLeaves({ treeRef }: { treeRef: React.RefObject<HT
const ctx = canvas.getContext("2d")!;
let animId: number;
const leaves: Leaf[] = [];
const MAX_LEAVES = 50;
const MAX_LEAVES = 36;
const frameInterval = 1000 / 30;
let lastFrame = 0;
let isVisible = true;
let isRunning = false;
let treeBounds = { left: 0, top: 0, width: 0 };
let canvasBounds = { left: 0, top: 0 };
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
function resize() {
function measure() {
const parent = canvas.parentElement;
const rect = parent?.getBoundingClientRect();
canvas.width = Math.max(1, Math.round(rect?.width || window.innerWidth));
canvas.height = Math.max(1, Math.round(rect?.height || window.innerHeight));
}
resize();
window.addEventListener("resize", resize);
function spawnLeaf(): Leaf {
const treeRect = treeRef.current?.getBoundingClientRect();
const canvasRect = canvas.getBoundingClientRect();
const spawnY = treeRect ? treeRect.top - canvasRect.top + TRUNK_TOP_CSS : canvas.height * 0.4;
const spawnX = treeRect
? treeRect.left - canvasRect.left + Math.random() * treeRect.width * 0.8 + treeRect.width * 0.1
: Math.random() * canvas.width * 0.6 + canvas.width * 0.2;
treeBounds = treeRect
? { left: treeRect.left, top: treeRect.top, width: treeRect.width }
: { left: canvasRect.left + canvas.width * 0.2, top: canvasRect.top + canvas.height * 0.4, width: canvas.width * 0.6 };
canvasBounds = { left: canvasRect.left, top: canvasRect.top };
}
measure();
const resizeObserver = new ResizeObserver(measure);
if (canvas.parentElement) resizeObserver.observe(canvas.parentElement);
if (treeRef.current) resizeObserver.observe(treeRef.current);
function spawnLeaf(): Leaf {
const spawnY = treeBounds.top - canvasBounds.top + TRUNK_TOP_CSS;
const spawnX = treeBounds.left - canvasBounds.left + Math.random() * treeBounds.width * 0.8 + treeBounds.width * 0.1;
return {
x: spawnX,
y: spawnY,
@@ -58,7 +69,11 @@ export default function FallingLeaves({ treeRef }: { treeRef: React.RefObject<HT
let spawnTimer = 0;
function draw() {
function draw(timestamp: number) {
if (!isRunning) return;
animId = requestAnimationFrame(draw);
if (timestamp - lastFrame < frameInterval) return;
lastFrame = timestamp;
ctx.clearRect(0, 0, canvas.width, canvas.height);
spawnTimer++;
@@ -90,14 +105,37 @@ export default function FallingLeaves({ treeRef }: { treeRef: React.RefObject<HT
}
}
}
function start() {
if (reducedMotion || isRunning || !isVisible || document.hidden) return;
isRunning = true;
animId = requestAnimationFrame(draw);
}
draw();
function stop() {
isRunning = false;
if (animId) cancelAnimationFrame(animId);
}
const intersectionObserver = new IntersectionObserver(([entry]) => {
isVisible = entry.isIntersecting;
if (isVisible) start();
else stop();
});
const onVisibilityChange = () => {
if (document.hidden) stop();
else start();
};
intersectionObserver.observe(canvas);
document.addEventListener("visibilitychange", onVisibilityChange);
start();
return () => {
cancelAnimationFrame(animId);
window.removeEventListener("resize", resize);
stop();
intersectionObserver.disconnect();
resizeObserver.disconnect();
document.removeEventListener("visibilitychange", onVisibilityChange);
};
}, []);