ai generated solutions to our ai generated problems
This commit is contained in:
+55
-23
@@ -189,6 +189,23 @@ function buildTree(seed: number) {
|
||||
}
|
||||
const WOOD_COLORS = ['', '#c96303', '#c96303', '#c96303', '#321901'];
|
||||
const LEAF_COLORS = ['', '#ed5145', '#fdb068', '#fee5cd'];
|
||||
const GROUND_COLORS = ['#fee5cd', '#fdca9b', '#fdb068'];
|
||||
const GRASS_COLORS = ['#ed5145', '#fb7b04', '#c96303', '#f17c74'];
|
||||
|
||||
function hexToRgba(hex: string) {
|
||||
return [
|
||||
parseInt(hex.slice(1, 3), 16),
|
||||
parseInt(hex.slice(3, 5), 16),
|
||||
parseInt(hex.slice(5, 7), 16),
|
||||
255,
|
||||
];
|
||||
}
|
||||
|
||||
const COLOR_RGBA = new Map(
|
||||
[...WOOD_COLORS, ...LEAF_COLORS, ...GROUND_COLORS, ...GRASS_COLORS]
|
||||
.filter(Boolean)
|
||||
.map((color) => [color, hexToRgba(color)]),
|
||||
);
|
||||
|
||||
export const TRUNK_TOP_CSS = (H - 150) + 10;
|
||||
|
||||
@@ -201,31 +218,37 @@ function renderTreeCanvas() {
|
||||
const ctx = canvas.getContext("2d")!;
|
||||
canvas.width = W * PX;
|
||||
canvas.height = H * PX;
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
|
||||
const { woodGrid, leafGrid } = buildTree(55);
|
||||
const pixelCanvas = document.createElement("canvas");
|
||||
const pixelCtx = pixelCanvas.getContext("2d")!;
|
||||
pixelCanvas.width = W;
|
||||
pixelCanvas.height = H;
|
||||
const image = pixelCtx.createImageData(W, H);
|
||||
|
||||
function setPixel(x: number, y: number, color: string) {
|
||||
const rgba = COLOR_RGBA.get(color)!;
|
||||
const index = (y * W + x) * 4;
|
||||
image.data[index] = rgba[0];
|
||||
image.data[index + 1] = rgba[1];
|
||||
image.data[index + 2] = rgba[2];
|
||||
image.data[index + 3] = rgba[3];
|
||||
}
|
||||
|
||||
for (let y = 0; y < H; y++)
|
||||
for (let x = 0; x < W; x++) {
|
||||
const v = woodGrid[y * W + x];
|
||||
if (v) {
|
||||
ctx.fillStyle = WOOD_COLORS[v] ?? '#321901';
|
||||
ctx.fillRect(x * PX, y * PX, PX, PX);
|
||||
}
|
||||
if (v) setPixel(x, y, WOOD_COLORS[v] ?? '#321901');
|
||||
}
|
||||
|
||||
for (let y = 0; y < H; y++)
|
||||
for (let x = 0; x < W; x++) {
|
||||
const v = leafGrid[y * W + x];
|
||||
if (v) {
|
||||
ctx.fillStyle = LEAF_COLORS[v];
|
||||
ctx.fillRect(x * PX, y * PX, PX, PX);
|
||||
}
|
||||
if (v) setPixel(x, y, LEAF_COLORS[v]);
|
||||
}
|
||||
|
||||
const GROUND_Y = H - 50;
|
||||
const groundColors = ['#fee5cd', '#fdca9b', '#fdb068'];
|
||||
const grassColors = ['#ed5145', '#fb7b04', '#c96303', '#f17c74'];
|
||||
|
||||
let gs = 12345;
|
||||
function grassRand() {
|
||||
@@ -239,8 +262,7 @@ function renderTreeCanvas() {
|
||||
for (let y = groundTop; y < H; y++) {
|
||||
const depth = (y - groundTop) / (H - groundTop);
|
||||
const ci = depth < 0.3 ? 0 : depth < 0.7 ? 1 : 2;
|
||||
ctx.fillStyle = groundColors[ci];
|
||||
ctx.fillRect(x * PX, y * PX, PX, PX);
|
||||
setPixel(x, y, GROUND_COLORS[ci]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,16 +271,17 @@ function renderTreeCanvas() {
|
||||
const wave = Math.sin(x * 0.05) * 3 + Math.sin(x * 0.12) * 2;
|
||||
const surfaceY = Math.round(GROUND_Y + wave);
|
||||
const bladeH = Math.floor(grassRand() * 4) + 2;
|
||||
const color = grassColors[Math.floor(grassRand() * grassColors.length)];
|
||||
ctx.fillStyle = color;
|
||||
const color = GRASS_COLORS[Math.floor(grassRand() * GRASS_COLORS.length)];
|
||||
for (let b = 0; b < bladeH; b++) {
|
||||
ctx.fillRect(x * PX, (surfaceY - b - 1) * PX, PX, PX);
|
||||
setPixel(x, surfaceY - b - 1, color);
|
||||
}
|
||||
if (grassRand() > 0.6 && x + 1 < W) {
|
||||
ctx.fillRect((x + 1) * PX, (surfaceY - 1) * PX, PX, PX);
|
||||
setPixel(x + 1, surfaceY - 1, color);
|
||||
}
|
||||
}
|
||||
|
||||
pixelCtx.putImageData(image, 0, 0);
|
||||
ctx.drawImage(pixelCanvas, 0, 0, canvas.width, canvas.height);
|
||||
cachedTreeCanvas = canvas;
|
||||
return canvas;
|
||||
}
|
||||
@@ -272,12 +295,21 @@ const Tree = forwardRef<HTMLCanvasElement>(function Tree(_, ref) {
|
||||
const canvasRef = (ref as React.RefObject<HTMLCanvasElement>) ?? internalRef;
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = canvasRef.current!;
|
||||
const ctx = canvas.getContext("2d")!;
|
||||
canvas.width = W * PX;
|
||||
canvas.height = H * PX;
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(renderTreeCanvas(), 0, 0);
|
||||
const canvas = canvasRef.current;
|
||||
if (!canvas) return undefined;
|
||||
|
||||
const draw = () => {
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) return;
|
||||
canvas.width = W * PX;
|
||||
canvas.height = H * PX;
|
||||
ctx.drawImage(renderTreeCanvas(), 0, 0);
|
||||
};
|
||||
const requestIdle = window.requestIdleCallback ?? ((callback) => window.setTimeout(callback, 100));
|
||||
const cancelIdle = window.cancelIdleCallback ?? window.clearTimeout;
|
||||
const idleId = requestIdle(draw, { timeout: 700 });
|
||||
|
||||
return () => cancelIdle(idleId);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user