import { JSX } from "preact"; import { Main, render_and_copy } from "./common.tsx"; const peopleify = (...people: string[]): string[] => // non-breaking space v people.map(p => `${p}\u202fpeople`); const animation_length = (num_items: number): number => /*num_items / 5*/ 3; const wheel_style = ( num_items: number, width?: number, shl?: number, n?: number ): JSX.CSSProperties => ({ transform: `translateY(calc(2rem * -${num_items}))`, animation: `${animation_length( num_items )}s ease-in-out reverse none running spin`, width: width ? `width: ${width * 100}%` : undefined, marginLeft: shl && n ? `-${shl * (n + 1)}px` : undefined, }); const get_delays = (...lengths: number[]): number[] => { const out = [0]; for (const l of lengths) { out.push((out.at(-1) ?? 0) + animation_length(l)); } return out; }; export const Wheel = ({ items, width, calc_width, shl, n, classes, }: { items: string[]; width?: number; calc_width?: number; shl?: number; n?: number; classes: string[]; }) => ( <details class="wheel" style={width ? `width: ${width * 100}%;` : ""}> <summary class={classes ? classes.join(" ") : ""}> {/* {...items.map((i: string) => <div class="wheel-item">{i}</div>)} */} </summary> <div class={`wheel-inner ${classes ? classes.join(" ") : ""}`} style={wheel_style(items.length, width)} > {/* <div class="wheel-item empty"></div> */} {...items.map((item, i) => ( <div class={`wheel-item ${i + 1 == items.length ? "last" : ""}`} style={ calc_width && n ? `margin-left: -${calc_width * n + (shl ?? 0)}px;` : "" } > {item} </div> ))} </div> </details> ); function slices<T>(arr: T[]): T[][] { return arr.map((_, i) => arr.slice(0, i)); } export function weird_slices<T>(arr: T[]): T[][] { console.log(arr.map(item => [...arr.filter(t => t != item), item])); return arr.map(item => [...arr.filter(t => t != item), item]); } export const MultiWheel = ({ items, calc_width, shl, type, }: { items: string[]; calc_width?: number; shl?: number; type: string; }) => ( <span class={`multiwheel ${type ? type : ""}`}> {...weird_slices(items).map((sliced_items, n) => ( <Wheel items={sliced_items} width={1 / items.length} calc_width={calc_width} shl={shl} n={n} classes={[type]} /> ))} <Wheel items={items} classes={["invisible", type]} /> </span> ); // i'll probably just hardcode the delays... lame but w/e // nope // it would be possible to have it so the final text is actually properyly selectable maybe but eh const Take = ({ subjects, objects, adjectives, }: { subjects: string[]; objects: string[]; adjectives: string[]; }) => ( <div class="take"> <MultiWheel calc_width={11.4333} shl={46} type="subjects" items={subjects} />{" "} <div class="bridge">who eat</div>{" "} <MultiWheel calc_width={4.7} shl={40} type="objects" items={objects} />{" "} <div class="bridge">are</div>{" "} <MultiWheel calc_width={8} type="adjectives" items={adjectives} /> </div> ); const Checkmark = () => ( <img class="checkmark" src="https://static.pyrope.net/white-twitter-checkmark.png" alt="the old, white twitter verified checkmark" /> ); const Author = () => ( <div class="author"> <img class="pfp" src="https://static.pyrope.net/phoebe_bridgers-pfp.jpg" alt="a picture of a blonde, white woman wearing a black coat and looking at her phone. presumably phoebe bridgers" /> <div class="names"> <div class="display-name"> traitor joe <Checkmark /> </div> <div class="username">@phoebe_bridgers</div> </div> </div> ); const Info = () => ( <div class="info"> <span class="time">10:02 PM</span> ·{" "} <span class="date">Feb 20, 2021</span> ·{" "} <span class="device">Twitter for iPhone</span> </div> ); const Stats = () => ( <div class="stats"> <span class="retweets"> <span class="stat">3,228</span> Retweets </span> <span class="quote-tweets"> <span class="stat">803</span> Quote Tweets </span> <span class="likes"> <span class="stat">39.3K</span> Likes </span> </div> ); // might want to have the final item be seperate // turned out to be unnecessary render_and_copy( <Main> <Author /> <Take subjects={peopleify( "poor", "fat", "dumb", "tall", "short", "poor", "fat", "dumb", "tall", "hot" )} objects={[ "apples", "bread", "pasta", "candy", "rice", "beans", "apples", "bread", "candy", "rice", "beans", "apples", "bread", "pasta", "candy", "rice", "croissants", ]} adjectives={[ "vibes", "mean", "dumb", "cool", "hot", "stupid", "funny", "vibes", "mean", "dumb", "cool", "hot", "stupid", "dangerous", ]} /> <Info /> <hr /> <Stats /> <hr /> <div class="bottom"></div> </Main> );