diff --git a/src/App.tsx b/src/App.tsx index 6867732..f148047 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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 = ( - - - - - - - - - ); - - 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 ( diff --git a/src/useBackground.tsx b/src/useBackground.tsx new file mode 100644 index 0000000..216a80f --- /dev/null +++ b/src/useBackground.tsx @@ -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 = ( + + + + + + + + + ); + + return { + regenerate, + svg: `data:image/svg+xml;base64,${window.btoa( + ReactDOMServer.renderToString(noise) + )}`, + backgrounds: background, + }; +}; + +export default useBackground;