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;
|
2023-07-10 15:57:51 -04:00
|
|
|
|
|
2023-07-12 05:21:45 -04:00
|
|
|
|
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(
|
2023-07-10 15:57:51 -04:00
|
|
|
|
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,
|
|
|
|
|
});
|
2023-07-10 15:57:51 -04:00
|
|
|
|
|
|
|
|
|
const get_delays = (...lengths: number[]): number[] => {
|
2023-07-12 23:20:19 -04:00
|
|
|
|
const out = [0];
|
2023-07-10 15:57:51 -04:00
|
|
|
|
for (const l of lengths) {
|
|
|
|
|
out.push((out.at(-1) ?? 0) + animation_length(l));
|
|
|
|
|
}
|
|
|
|
|
return out;
|
|
|
|
|
};
|
2023-07-10 16:50:36 -04:00
|
|
|
|
|
2023-07-22 16:19:42 -04:00
|
|
|
|
export const Wheel = ({
|
2023-07-12 14:15:53 -04:00
|
|
|
|
items,
|
|
|
|
|
width,
|
|
|
|
|
calc_width,
|
|
|
|
|
shl,
|
|
|
|
|
n,
|
|
|
|
|
classes,
|
|
|
|
|
}: {
|
|
|
|
|
items: string[];
|
|
|
|
|
width?: number;
|
|
|
|
|
calc_width?: number;
|
|
|
|
|
shl?: number;
|
|
|
|
|
n?: number;
|
|
|
|
|
classes: string[];
|
|
|
|
|
}) => (
|
2023-07-11 16:35:51 -04:00
|
|
|
|
<details class="wheel" style={width ? `width: ${width * 100}%;` : ""}>
|
|
|
|
|
<summary class={classes ? classes.join(" ") : ""}>
|
2023-07-12 05:21:45 -04:00
|
|
|
|
{/* {...items.map((i: string) => <div class="wheel-item">{i}</div>)} */}
|
2023-07-10 16:50:36 -04:00
|
|
|
|
</summary>
|
2023-07-11 14:19:46 -04:00
|
|
|
|
<div
|
|
|
|
|
class={`wheel-inner ${classes ? classes.join(" ") : ""}`}
|
2023-07-12 05:21:45 -04:00
|
|
|
|
style={wheel_style(items.length, width)}
|
2023-07-11 14:19:46 -04:00
|
|
|
|
>
|
2023-07-10 16:50:36 -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" : ""}`}
|
2023-07-12 05:21:45 -04:00
|
|
|
|
style={
|
|
|
|
|
calc_width && n
|
|
|
|
|
? `margin-left: -${calc_width * n + (shl ?? 0)}px;`
|
|
|
|
|
: ""
|
|
|
|
|
}
|
2023-07-10 19:52:09 -04:00
|
|
|
|
>
|
|
|
|
|
{item}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
2023-07-10 15:57:51 -04:00
|
|
|
|
</div>
|
2023-07-10 16:50:36 -04:00
|
|
|
|
</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-22 16:19:42 -04:00
|
|
|
|
export function weird_slices<T>(arr: T[]): T[][] {
|
2023-07-11 16:35:51 -04:00
|
|
|
|
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-22 16:19:42 -04:00
|
|
|
|
export const MultiWheel = ({
|
2023-07-12 14:15:53 -04:00
|
|
|
|
items,
|
|
|
|
|
calc_width,
|
|
|
|
|
shl,
|
|
|
|
|
type,
|
|
|
|
|
}: {
|
|
|
|
|
items: string[];
|
|
|
|
|
calc_width?: number;
|
|
|
|
|
shl?: number;
|
|
|
|
|
type: string;
|
|
|
|
|
}) => (
|
2023-07-11 16:35:51 -04:00
|
|
|
|
<span class={`multiwheel ${type ? type : ""}`}>
|
2023-07-12 05:21:45 -04:00
|
|
|
|
{...weird_slices(items).map((sliced_items, n) => (
|
2023-07-11 16:35:51 -04:00
|
|
|
|
<Wheel
|
2023-07-12 05:21:45 -04:00
|
|
|
|
items={sliced_items}
|
2023-07-11 16:35:51 -04:00
|
|
|
|
width={1 / items.length}
|
2023-07-12 05:21:45 -04:00
|
|
|
|
calc_width={calc_width}
|
|
|
|
|
shl={shl}
|
2023-07-11 16:35:51 -04:00
|
|
|
|
n={n}
|
2023-07-12 14:15:53 -04:00
|
|
|
|
classes={[type]}
|
2023-07-11 16:35:51 -04:00
|
|
|
|
/>
|
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
|
|
|
|
);
|
|
|
|
|
|
2023-07-10 15:57:51 -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[];
|
|
|
|
|
}) => (
|
2023-07-10 16:50:36 -04:00
|
|
|
|
<div class="take">
|
2023-07-12 05:21:45 -04:00
|
|
|
|
<MultiWheel
|
|
|
|
|
calc_width={11.4333}
|
|
|
|
|
shl={46}
|
|
|
|
|
type="subjects"
|
|
|
|
|
items={subjects}
|
|
|
|
|
/>{" "}
|
2023-07-11 16:35:51 -04:00
|
|
|
|
<div class="bridge">who eat</div>{" "}
|
2023-07-12 05:21:45 -04:00
|
|
|
|
<MultiWheel calc_width={4.7} shl={40} type="objects" items={objects} />{" "}
|
2023-07-11 16:35:51 -04:00
|
|
|
|
<div class="bridge">are</div>{" "}
|
2023-07-12 05:21:45 -04:00
|
|
|
|
<MultiWheel calc_width={8} type="adjectives" items={adjectives} />
|
2023-07-10 16:50:36 -04:00
|
|
|
|
</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
|
2023-07-10 15:57:51 -04:00
|
|
|
|
// turned out to be unnecessary
|
2023-07-12 14:15:53 -04:00
|
|
|
|
render_and_copy(
|
2023-07-10 16:51:04 -04:00
|
|
|
|
<Main>
|
2023-07-10 19:52:09 -04:00
|
|
|
|
<Author />
|
2023-07-10 16:51:04 -04:00
|
|
|
|
<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>
|
2023-07-10 16:51:04 -04:00
|
|
|
|
</Main>
|
2023-07-10 14:52:20 -04:00
|
|
|
|
);
|