cohost/html/train.tsx
2023-11-27 00:17:58 -05:00

81 lines
2 KiB
TypeScript

import { render_and_copy } from "./common.tsx";
import { ComponentChildren } from "preact";
const Rail = ({ rotation, r }: { rotation: string; r: string }) => (
<div
style={{
transform: `rotate(${rotation}) translateX(${r})`,
gridArea: "1/1",
}}
>
🪜
</div>
);
const Track = ({
segments,
r,
children,
}: {
segments: number;
r: string;
children?: ComponentChildren;
}) => (
<div
style={{
display: "grid",
width: "100%",
aspectRatio: "2/1",
justifyItems: "center",
alignItems: "center",
transform: "rotateX(60deg)",
margin: "0 auto",
perspective: "1000px",
perspectiveOrigin: "top",
}}
>
{...Array.from({ length: segments }, (_, i) => (
// deg is actually more space-efficient lel
<Rail rotation={`${(360 / segments) * i}deg`} r={r} />
))}
{children}
</div>
);
const Train = ({
children,
delay_s,
}: {
children: ComponentChildren;
delay_s: number;
}) => (
<div
id="contrainer"
style={`animation: spin 20s ${
delay_s - 20
}s linear reverse infinite; transform-origin: center; width: 20.5rem; grid-area: 1/1; transform-style: preserve-3d;`}
>
<div
id="train"
style="font-size: 2rem; width: fit-content; transform-style: preserve-3d; transform: rotate(-90deg)"
>
{children}
</div>
</div>
);
// we can have things with animation delays for both the engine and the cars
// configurable animation length for sure
// it's so funny seeing css crimes from like a year ago and they are just like on a different level
render_and_copy(
<Track segments={60} r={"8rem"}>
<Train delay_s={0}>🚂</Train>
<Train delay_s={0.8}>🚃</Train>
<Train delay_s={1.6}>🚃</Train>
<Train delay_s={2.4}>🚃</Train>
<Train delay_s={3.2}>🚃</Train>
</Track>
);