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))", ]} /> );