Refactor gradient & noise gen. in useBackground.tsx

This commit is contained in:
Xevion
2022-11-24 22:53:20 -06:00
parent 8aca135803
commit df4193e94c
2 changed files with 86 additions and 55 deletions

View File

@@ -1,69 +1,19 @@
import Chance from "chance";
import ReactDOMServer from "react-dom/server";
import { useEventListener, useWindowSize } from "usehooks-ts";
import { useState } from "react";
import { getEdgePoint } from "@/utils";
const chance = Chance();
const colors = [
"#ed625d",
"#42b6c6",
"#f79f88",
"#446ba6",
"#4b95f0",
"#d16ba5",
];
const generateBackground = () => {
return chance.pickset(colors, 5).map((color) => {
const [x, y] = getEdgePoint(chance.integer({ min: 0, max: 100 }), 100, 100);
return `radial-gradient(farthest-corner at ${x}% ${y}%, ${chance.pickone(
colors
)}, ${chance.pickone(colors)}, transparent 100%)`;
});
};
import useBackground from "./useBackground";
function App() {
const { width, height } = useWindowSize();
const [background, setBackground] = useState(generateBackground());
const { svg, backgrounds, regenerate } = useBackground({ width, height, ratio: 0.3 });
useEventListener("keydown", (e) => {
if (e.code != "Enter") return;
e.preventDefault();
setBackground(generateBackground());
e.preventDefault();
regenerate();
});
const ratio = 0.3;
const svgWidth = Math.ceil((width ?? 1920) * ratio);
const svgHeight = Math.ceil((height ?? 1080) * ratio);
console.log({ svgWidth, svgHeight });
const noise = (
<svg
viewBox={`0 0 ${svgWidth} ${svgHeight}`}
xmlns="http://www.w3.org/2000/svg"
>
<filter id="noiseFilter">
<feTurbulence
type="fractalNoise"
baseFrequency="2"
numOctaves="2"
stitchTiles="stitch"
/>
</filter>
<g opacity={0.9}>
<rect width="100%" height="100%" filter="url(#noiseFilter)" />
</g>
</svg>
);
const svg = `data:image/svg+xml;base64,${window.btoa(
ReactDOMServer.renderToString(noise)
)}`;
const appStyle = {
background: [`url("${svg}")`, ...background].join(", "),
background: [`url("${svg}")`, ...backgrounds].join(", "),
};
return (

81
src/useBackground.tsx Normal file
View File

@@ -0,0 +1,81 @@
import { Chance } from "chance";
import { useEffect, useMemo, useState } from "react";
import ReactDOMServer from "react-dom/server";
import { getEdgePoint } from "./utils";
interface useBackgroundProps {
width: number;
height: number;
ratio: number;
}
interface useBackgroundReturn {
regenerate: () => void;
backgrounds: string[];
svg: string;
}
const chance = Chance();
const palettes = [
// ["#5e1e1e", "#141414", "#400000", "#7a0000", "#2b0059", "#000c59", "#850082", "#850052"],
["#ed625d", "#42b6c6", "#f79f88", "#446ba6", "#4b95f0", "#d16ba5"],
];
const generateBackground = (): string[] => {
const palette = chance.pick(palettes);
return Array(5)
.fill(null)
.map(() => chance.pickone(palette))
.map((color) => {
const [x, y] = getEdgePoint(
chance.integer({ min: 0, max: 400 }),
100,
100
);
return `radial-gradient(farthest-corner at ${x}% ${y}%, ${color}, transparent 100%)`;
});
};
const useBackground = ({
width,
height,
ratio,
}: useBackgroundProps): useBackgroundReturn => {
const [background, setBackground] = useState(generateBackground());
const regenerate = () => {
setBackground(generateBackground());
};
const svgWidth = Math.ceil((width ?? 1920) * ratio);
const svgHeight = Math.ceil((height ?? 1080) * ratio);
const noise = (
<svg
viewBox={`0 0 ${svgWidth} ${svgHeight}`}
xmlns="http://www.w3.org/2000/svg"
>
<filter id="noiseFilter">
<feTurbulence
type="fractalNoise"
baseFrequency="2.1"
numOctaves="2"
seed={chance.natural()}
stitchTiles="stitch"
/>
</filter>
<g opacity={0.9}>
<rect width="100%" height="100%" filter="url(#noiseFilter)" />
</g>
</svg>
);
return {
regenerate,
svg: `data:image/svg+xml;base64,${window.btoa(
ReactDOMServer.renderToString(noise)
)}`,
backgrounds: background,
};
};
export default useBackground;