sunshine: feeling a bit stuck

This commit is contained in:
mehbark 2023-09-06 21:01:47 -04:00
parent 93948ae90f
commit 7bf25db6a3
2 changed files with 106 additions and 24 deletions

View file

@ -197,10 +197,13 @@ export const jitter = (n: number) => n * (Math.random() - 0.5);
export const svg_url = (svg: string) => `data:image/svg+xml,${encodeURI(svg)}`;
// something higher-level might be worthwhile...
// could namespace; e.g. css.font.sans_serif
export const css = {
url(href: string) {
return `url('${href}')`;
},
px(n: number) {
return `${n}px`;
},
@ -210,8 +213,43 @@ export const css = {
rem(n: number) {
return `${n}rem`;
},
deg(n: number) {
return `${n}deg`;
},
rad(n: number) {
return `${n}rad`;
},
turn(n: number) {
return `${n}turn`;
},
// now i feel like this could be generalizable
// but js metaprogramming SUCKS
transform(...ts: string[]) {
return ts.join(" ");
},
rotate(by: string) {
return `rotate(${by})`;
},
translateX(by: string) {
return `translateX(${by})`;
},
translateY(by: string) {
return `translateY(${by})`;
},
translate(x: string, y: string) {
return `translate(${x}, ${y})`;
},
fontstack(...fonts: string[]) {
return fonts.join(", ");
},
// # ruby i wont you ..
inline_block: "inline-block",
block: "block",
grid: "grid",
flex: "flex",
fit_content: "fit-content",
min_content: "min-content",
max_content: "max-content",
} as const;

View file

@ -1,29 +1,73 @@
import { css, render_and_copy, svg_url } from "./common.tsx";
const svg = `
<svg id="filterSource" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<filter id="displacement" filterUnits="userSpaceOnUse">
<!-- this is just a base64 encoded PNG with a simple linear gradient -->
<!-- this may not be exactly what you want, but you can adjust the R and B channels to displace the element however you like. -->
<feImage href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAdhAAAHYQGVw7i2AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAGlJREFUaIHtz6ENwEAMxVBfUWn3H7Kw8LpCdMjAT/osIF7AZuAGnsMt4D3cN3kOuIZ3eoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNj9ceBBjuV6HJAAAAABJRU5ErkJggg==" result="dispMap" />
<feDisplacementMap
in="SourceGraphic"
in2="dispMap"
scale="10"
xChannelSelector="B"
yChannelSelector="R" />
</filter>
</svg>
`.trim();
const displace =
(width: number, amplitude = 1) =>
(t: number) =>
amplitude * Math.sin((Math.PI / width) * t);
render_and_copy(
const rotation = css.rotate(css.deg(-20));
const Row = ({
children,
max_width = 10,
}: {
children: string;
max_width?: number;
}) => {
const d = displace(max_width);
const out = children.split("").map((c, i) => (
<div
style={{
display: css.inline_block,
filter: css.url(svg_url(svg) + "#displacement"),
height: css.rem(10),
transform: css.transform(
css.translateY(css.rem(-d(i)))
// rotation
),
// width: css.min_content,
// height: css.min_content,
color: "black",
}}
>
yo what's up i am a chuckya
{c}
</div>
));
return (
<div
style={{
// transform: css.transform(
// css.rotate(css.deg(-20)),
// css.translate(css.rem(2), css.rem(-4))
// ),
display: css.flex,
fontFamily: css.fontstack(
"Comic Sans MS",
"cursive",
"sans-serif"
),
}}
>
{...out}
</div>
);
};
const TextBox = ({ lines }: { lines: string[] }) => {
const max_width = Math.max(...lines.map(l => l.length));
return (
<div
style={{
transform: css.transform(rotation),
height: css.rem(30),
alignItems: "center",
}}
>
{...lines.map(line => <Row max_width={max_width}>{line}</Row>)}
</div>
);
};
render_and_copy(
<TextBox
lines={["Use that FLUDD to", "move around and", "get red coins."]}
/>
);