cohost/html/hot_people_who_eat_croissants_are_dangerous.tsx

241 lines
6.2 KiB
TypeScript
Raw Normal View History

2023-07-12 14:15:53 -04:00
import { JSX } from "preact";
import { Main, render_and_copy } from "./common.tsx";
2023-07-10 14:52:20 -04:00
2023-07-10 14:57:18 -04:00
const peopleify = (...people: string[]): string[] =>
2023-07-11 15:25:40 -04:00
// non-breaking space v
people.map(p => `${p}\u202fpeople`);
2023-07-10 14:57:18 -04:00
2023-07-10 22:37:47 -04:00
const animation_length = (num_items: number): number => /*num_items / 5*/ 3;
const wheel_style = (
num_items: number,
width?: number,
shl?: number,
n?: number
2023-07-12 14:15:53 -04:00
): JSX.CSSProperties => ({
transform: `translateY(calc(2rem * -${num_items}))`,
animation: `${animation_length(
num_items
2023-07-12 14:15:53 -04:00
)}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[] => {
2023-07-12 23:20:19 -04:00
const out = [0];
for (const l of lengths) {
out.push((out.at(-1) ?? 0) + animation_length(l));
}
return out;
};
2023-07-12 14:15:53 -04:00
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>
2023-07-11 14:19:46 -04:00
<div
class={`wheel-inner ${classes ? classes.join(" ") : ""}`}
style={wheel_style(items.length, width)}
2023-07-11 14:19:46 -04:00
>
{/* <div class="wheel-item empty"></div> */}
2023-07-12 14:15:53 -04:00
{...items.map((item, i) => (
2023-07-10 19:52:09 -04:00
<div
class={`wheel-item ${i + 1 == items.length ? "last" : ""}`}
style={
calc_width && n
? `margin-left: -${calc_width * n + (shl ?? 0)}px;`
: ""
}
2023-07-10 19:52:09 -04:00
>
{item}
</div>
))}
</div>
</details>
2023-07-10 14:52:20 -04:00
);
2023-07-11 12:43:32 -04:00
function slices<T>(arr: T[]): T[][] {
return arr.map((_, i) => arr.slice(0, i));
}
2023-07-11 14:19:46 -04:00
function weird_slices<T>(arr: T[]): T[][] {
console.log(arr.map(item => [...arr.filter(t => t != item), item]));
2023-07-11 14:19:46 -04:00
return arr.map(item => [...arr.filter(t => t != item), item]);
}
2023-07-12 14:15:53 -04:00
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}
2023-07-12 14:15:53 -04:00
classes={[type]}
/>
2023-07-11 12:43:32 -04:00
))}
2023-07-12 14:15:53 -04:00
<Wheel items={items} classes={["invisible", type]} />
2023-07-11 15:25:40 -04:00
</span>
2023-07-11 12:43:32 -04:00
);
// i'll probably just hardcode the delays... lame but w/e
2023-07-10 19:52:09 -04:00
// nope
// it would be possible to have it so the final text is actually properyly selectable maybe but eh
2023-07-12 14:15:53 -04:00
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>
);
2023-07-10 14:52:20 -04:00
2023-07-12 14:15:53 -04:00
const Checkmark = () => (
2023-07-10 19:52:09 -04:00
<img
class="checkmark"
src="https://static.pyrope.net/white-twitter-checkmark.png"
alt="the old, white twitter verified checkmark"
/>
);
2023-07-12 14:15:53 -04:00
const Author = () => (
2023-07-10 19:52:09 -04:00
<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>
);
2023-07-12 14:15:53 -04:00
const Info = () => (
2023-07-10 22:37:47 -04:00
<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>
);
2023-07-12 14:15:53 -04:00
const Stats = () => (
2023-07-10 22:37:47 -04:00
<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>
);
2023-07-10 14:52:20 -04:00
// might want to have the final item be seperate
// turned out to be unnecessary
2023-07-12 14:15:53 -04:00
render_and_copy(
<Main>
2023-07-10 19:52:09 -04:00
<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",
]}
/>
2023-07-10 22:37:47 -04:00
<Info />
<hr />
<Stats />
<hr />
<div class="bottom"></div>
</Main>
2023-07-10 14:52:20 -04:00
);