ai generated solutions to our ai generated problems
This commit is contained in:
@@ -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);
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user