diff --git a/src/app/page.tsx b/src/app/page.tsx index 9f25edb..dab2f60 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -7,61 +7,99 @@ import Image from "next/image"; import React, { type JSX } from "react"; import { NavItems } from "../config/NavItems"; +const generateRandomColor = (): string => { + return `#${Math.floor(Math.random() * 16_777_215).toString(16). + padStart(6, "0")}`; +}; + +const getLuminance = (hexColor: string): number => { + const r = Number.parseInt(hexColor.slice(1, 3), 16); + const g = Number.parseInt(hexColor.slice(3, 5), 16); + const b = Number.parseInt(hexColor.slice(5, 7), 16); + + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + const a: [number, number, number] = [ r, g, b ].map((v) => { + const w = v / 255; + return w <= 0.039_28 + ? w / 12.92 + : Math.pow((w + 0.055) / 1.055, 2.4); + }) as [number, number, number]; + + const rl = a[0] * 0.2126; + const gl = a[1] * 0.7152; + const bl = a[2] * 0.0722; + return rl + gl + bl; +}; + +const adjustColorLuminosity + = (hexColor: string, luminosityChange: number): string => { + let r = Number.parseInt(hexColor.slice(1, 3), 16); + let g = Number.parseInt(hexColor.slice(3, 5), 16); + let b = Number.parseInt(hexColor.slice(5, 7), 16); + r = Math.round(r * luminosityChange); + g = Math.round(g * luminosityChange); + b = Math.round(b * luminosityChange); + r = Math.min(255, Math.max(0, r)); + g = Math.min(255, Math.max(0, g)); + b = Math.min(255, Math.max(0, b)); + return `#${ + r.toString(16).padStart(2, "0") + }${g.toString(16).padStart(2, "0") + }${b.toString(16).padStart(2, "0")}`; + }; + +const generateColorPair = (): { background: string; color: string } => { + const backgroundColor = generateRandomColor(); + const backgroundLuminance = getLuminance(backgroundColor); + const textColor = backgroundLuminance > 0.5 ? + adjustColorLuminosity(backgroundColor, 0) : + adjustColorLuminosity(backgroundColor, 5); + + return { + background: backgroundColor, + color: textColor, + }; +}; + /** * Renders the main React component. * @returns A JSX element. */ const Home = (): JSX.Element => { return ( -
-
- - - -
-
-
-

{`Naomi Carrigan`}

- Naomi Carrigan -

{`Software Engineer`}

-

{`Community Manager`}

-
-
- {NavItems.map((item, index) => { - return ( - - {index % 2 === 1 - ? "🩷" - : "🩵"} {item.text} - - ); - })} -
-
-
+
+

{`Naomi Carrigan`}

+ Naomi Carrigan +

{`Software Engineer | Community Manager | VTuber`}

+ {NavItems.map((item, index) => { + const { background, color } = generateColorPair(); + return ( + + {index % 2 === 1 + ? "🩷" + : "🩵"} {item.text} + + ); + })} +
); }; diff --git a/src/components/footer.tsx b/src/components/footer.tsx index 08e4774..dea7871 100644 --- a/src/components/footer.tsx +++ b/src/components/footer.tsx @@ -7,7 +7,6 @@ import { faComments } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Crisp } from "crisp-sdk-web"; -import { usePathname } from "next/navigation"; import Script from "next/script"; import React, { type JSX } from "react"; @@ -20,12 +19,6 @@ export const Footer = (): JSX.Element | null => { if (typeof window !== "undefined") { Crisp.configure("5398ce41-4ceb-4e31-9049-4c784a70179a"); } - const pathname = usePathname(); - const isRootPath = pathname === "/"; - - if (isRootPath) { - return null; - } return (
{ setIsDarkMode(!isDarkMode); }, [ isDarkMode ]); - const pathname = usePathname(); - const isRootPath = pathname === "/"; - - if (isRootPath) { - return null; - } - return (