cohost/html/blowing-in-the-wind.tsx

89 lines
3.3 KiB
TypeScript

import { Main, n_of, pick_random, render_and_copy } from "./common.tsx";
// ⾋ is grass which is neat
// meh, this seems to be the least worst option
// random ascii rocks and bunnies and such might be neat but would
// be total possible actually so i'm going to do that now
const grass_chars = "^".split("");
// const grass_chars = ["^", '"', "'", ";", ":", "*", "+", "~"];
const grass_colors = ["#136D15", "#117C13", "#138510", "#268B07", "#41980A"];
// i want to keep this minimal (i want to have a lot of grass :])
// b works nicely i think
// generally kinda doubting if the ascii look jives with the rest of the idea
// looks terrible when synchronized obviously lol
// i'm going to need to be smarter and consider the position but that's going
// to be a lot more difficult
// i should really have more randomness utilities
const blade_delay = (x: number, y: number): number => {
const t = x + y;
return t + (Math.random() - 0.5) * 1.5;
// return Math.sin(t / 3) < 0 ? 3 * Math.sin(t) : Math.sin(t) / 4;
// const den = 3;
// return (
// (Math.sin(t / den) < 0 && Math.sin(t) < 0
// ? Math.sin(t) / den
// : Math.sin(t)) +
// (Math.random() - 0.5) * 1.5
// );
};
// truncing floats a bit could save a lot of bytes but eh
// should be a util obviously
// toFixed is sufficient for css stuff methinks
// you know it's a good css crime when using toFixed saves multiple kilobytes
const Blade = ({ x, y }: { x: number; y: number }) => (
<b
style={{
// transformOrigin: "bottom",
// transform: "translateX(0.5rem)",
animation: "spin infinite ease-in-out alternate",
transform: "translateX(0.5rem)",
// putting math knowledge to work :D
animationDelay: `${blade_delay(x, y).toFixed(2)}s`,
// having some randomness with the duration is a great idea!!
// maybe not with things being synchronized though!
// animationDuration: `${2.5 + Math.random() * 0}s`,
animationDuration: "6.5s",
color: pick_random(grass_colors),
// helps the squareness
overflow: "hidden",
}}
>
{pick_random(grass_chars)}
</b>
);
const Field = ({ width }: { width: number }) => (
<div
style={{
width: "100%",
aspectRatio: "1",
display: "grid",
gridTemplateRows: `repeat(${width}, 1fr)`,
gridTemplateColumns: `repeat(${width}, 1fr)`,
fontFamily: "monospace",
// brown doesn't really work because the grass isn't dense enough
// maybe a complete dfivorce isn't in order
backgroundColor: "black",
fontWeight: "bolder",
fontSize: "1.1rem",
}}
>
{new Array(width * width).fill(undefined).map((_, i) => (
<Blade x={i % width} y={Math.floor(i / width)} />
))}
</div>
);
// it's funny how the whole idea was to emulate waves of grass but then i just
// didn't do that because it's hawd :[
// okay, seeing how pretty the waves in the wrapped text of the source are has
// inspired me. i'm going to work on this tomorrow and do the hawd thing (waves)
// adding more grass doesn't really help and mainly just causes size problems
render_and_copy(<Field width={25} />);