cohost/html/bars.tsx

99 lines
2.3 KiB
TypeScript
Raw Normal View History

2023-07-12 23:20:19 -04:00
import { JSX } from "preact";
import { Main, render_and_copy } from "./common.tsx";
const Bar = ({
color,
animation_time,
side,
}: {
color: string;
animation_time: number;
side: "left" | "right";
}): JSX.Element => (
<div class="bar">
<div
class="bar-inner"
style={{
transform: `translateX(${side == "left" ? -100 : 100}%)`,
backgroundColor: color,
animation: `${animation_time}s alternate-reverse ease infinite spin`,
outline: `1px solid ${color}`,
}}
></div>
</div>
);
function coprime(a: number, b: number): boolean {
if (a == b) return false;
for (let i = 2; i < Math.min(a, b); i++) {
if (a % i == 0 && b % i == 0) {
return false;
}
}
return true;
}
function next_coprime(ns: number[]): number {
if (ns.length == 0) return 2;
for (let a = ns.at(-1) ?? 0; ; a++) {
let good = true;
for (const b of ns) {
if (!coprime(a, b)) good = false;
}
if (good) return a;
}
}
function gen_coprimes(to: number): number[] {
if (to <= 0) return [];
if (to == 1) return [2];
const xs = gen_coprimes(to - 1);
return [...xs, next_coprime(xs)];
}
const BarPair = ({
color,
animation_time,
num_bars,
}: {
color: string;
animation_time: number;
num_bars: number;
}): JSX.Element => (
<div class="bar-pair" style={{ height: `${(1 / num_bars) * 100}%` }}>
<Bar color={color} animation_time={animation_time} side="left" />
<Bar color={color} animation_time={animation_time} side="right" />
</div>
);
const Bars = ({ colors }: { colors: string[] }): JSX.Element => (
<Main>
{...colors.map((c, i) => (
<BarPair
color={c}
animation_time={2 ** i * 0.1}
num_bars={colors.length}
/>
))}
</Main>
);
render_and_copy(
<Bars
colors={[
"#FF6961",
"#FFB347",
"#FFFF99",
"#77DD77",
"#ADD8E6",
"#B19CD9",
"rgb(var(--color-longan))",
"rgb(var(--color-mango))",
"rgb(var(--color-strawberry))",
"rgb(var(--color-cherry))",
]}
/>
);