Noise & Gradient Generation

This commit is contained in:
Xevion
2022-11-24 19:13:52 -06:00
parent 7298ae0945
commit 8aca135803
5 changed files with 184 additions and 0 deletions

124
src/App.tsx Normal file
View File

@@ -0,0 +1,124 @@
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%)`;
});
};
function App() {
const { width, height } = useWindowSize();
const [background, setBackground] = useState(generateBackground());
useEventListener("keydown", (e) => {
if (e.code != "Enter") return;
e.preventDefault();
setBackground(generateBackground());
});
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(", "),
};
return (
<div style={appStyle} className="gradient">
<div className="font-inter min-w-[100vw] min-h-[100vh] bg-zinc-800/50 bg-blend-overlay">
<div className="grid grid-cols-12 w-full">
<div className="col-span-1" />
<div className="flex col-span-10 md:col-span-8 lg:col-span-6 offset-1 bg-white w-full min-h-[100vh] text-zinc-800">
<div className="m-3 p-5 border-y-[1px] border-zinc-100">
<div className="mb-3">
<h2 className="text-4xl tracking-wide font-semibold drop-shadow-xl">
Ryan Walters
</h2>
<span className="py-1 text-zinc-500">
Published on {new Date().toLocaleDateString()}
</span>
</div>
<div className="space-y-2">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
consequat lacus sit amet erat efficitur elementum. Fusce
hendrerit bibendum ipsum, sit amet volutpat augue egestas sed.
Curabitur ut blandit felis. Suspendisse euismod, orci quis
consectetur pretium, libero eros lobortis lacus, vel interdum
ex sem sed sapien. Aliquam erat volutpat. Curabitur tempus
faucibus lobortis. Nulla sodales ipsum sit amet ligula
elementum faucibus. Donec aliquam enim a arcu gravida tempus.
Etiam tempus lectus et mauris feugiat, vel imperdiet quam
mattis. Suspendisse urna enim, cursus quis nibh et, egestas
ultrices tortor. Quisque imperdiet elit molestie lorem
placerat posuere. Duis in dolor non elit tempor mattis. Proin
vehicula facilisis nibh.
</p>
<p>
Maecenas rhoncus, erat auctor scelerisque condimentum, nibh
magna tristique felis, vitae condimentum mi est quis dui.
Fusce non imperdiet massa. Sed varius ultrices odio non
faucibus. Pellentesque habitant morbi tristique senectus et
netus et malesuada fames ac turpis egestas. Pellentesque
semper pulvinar vehicula. Fusce vel convallis eros. Duis
cursus feugiat quam, quis sodales enim malesuada non.
Vestibulum ante ipsum primis in faucibus orci luctus et
ultrices posuere cubilia curae; Maecenas in efficitur elit,
sed suscipit magna. Duis finibus blandit leo vitae mollis. In
et est pulvinar, condimentum est sed, scelerisque nisl. Nunc
eleifend eros aliquet libero.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export default App;

35
src/index.scss Normal file
View File

@@ -0,0 +1,35 @@
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap");
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
body {
min-width: 100vw;
min-height: 100vh;
background-color: #242424;
}
.gradient {
filter: contrast(150%) brightness(90%);
background-blend-mode: overlay;
}

10
src/main.tsx Normal file
View File

@@ -0,0 +1,10 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.scss'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
)

14
src/utils.ts Normal file
View File

@@ -0,0 +1,14 @@
export const getEdgePoint = (
n: number,
width: number,
height: number
): [number, number] => {
const full = 2 * width + 2 * height;
if (n > full) n %= full;
if (n < 0) n = full - n;
if (n < width) return [n, 0];
if (n < width + height) return [width, n - width];
if (n < 2 * width + height) return [n - (2 * width + height), height];
return [0, height - (n - (2 * width + height))];
};

1
src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="vite/client" />