sunshine: feeling a bit stuck
This commit is contained in:
parent
93948ae90f
commit
7bf25db6a3
2 changed files with 106 additions and 24 deletions
|
@ -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)}`;
|
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 = {
|
export const css = {
|
||||||
url(href: string) {
|
url(href: string) {
|
||||||
return `url('${href}')`;
|
return `url('${href}')`;
|
||||||
},
|
},
|
||||||
|
|
||||||
px(n: number) {
|
px(n: number) {
|
||||||
return `${n}px`;
|
return `${n}px`;
|
||||||
},
|
},
|
||||||
|
@ -210,8 +213,43 @@ export const css = {
|
||||||
rem(n: number) {
|
rem(n: number) {
|
||||||
return `${n}rem`;
|
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",
|
inline_block: "inline-block",
|
||||||
block: "block",
|
block: "block",
|
||||||
grid: "grid",
|
grid: "grid",
|
||||||
flex: "flex",
|
flex: "flex",
|
||||||
|
fit_content: "fit-content",
|
||||||
|
min_content: "min-content",
|
||||||
|
max_content: "max-content",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -1,29 +1,73 @@
|
||||||
import { css, render_and_copy, svg_url } from "./common.tsx";
|
import { css, render_and_copy, svg_url } from "./common.tsx";
|
||||||
|
|
||||||
const svg = `
|
const displace =
|
||||||
<svg id="filterSource" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
(width: number, amplitude = 1) =>
|
||||||
<filter id="displacement" filterUnits="userSpaceOnUse">
|
(t: number) =>
|
||||||
<!-- this is just a base64 encoded PNG with a simple linear gradient -->
|
amplitude * Math.sin((Math.PI / width) * t);
|
||||||
<!-- 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" />
|
const rotation = css.rotate(css.deg(-20));
|
||||||
<feDisplacementMap
|
|
||||||
in="SourceGraphic"
|
const Row = ({
|
||||||
in2="dispMap"
|
children,
|
||||||
scale="10"
|
max_width = 10,
|
||||||
xChannelSelector="B"
|
}: {
|
||||||
yChannelSelector="R" />
|
children: string;
|
||||||
</filter>
|
max_width?: number;
|
||||||
</svg>
|
}) => {
|
||||||
`.trim();
|
const d = displace(max_width);
|
||||||
|
const out = children.split("").map((c, i) => (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
transform: css.transform(
|
||||||
|
css.translateY(css.rem(-d(i)))
|
||||||
|
// rotation
|
||||||
|
),
|
||||||
|
// width: css.min_content,
|
||||||
|
// height: css.min_content,
|
||||||
|
color: "black",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{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(
|
render_and_copy(
|
||||||
<div
|
<TextBox
|
||||||
style={{
|
lines={["Use that FLUDD to", "move around and", "get red coins."]}
|
||||||
display: css.inline_block,
|
/>
|
||||||
filter: css.url(svg_url(svg) + "#displacement"),
|
|
||||||
height: css.rem(10),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
yo what's up i am a chuckya
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue