From 83729c9950d973bc990b06c0fa46b4463c994ebc Mon Sep 17 00:00:00 2001 From: pahmiudahgede Date: Sun, 6 Jul 2025 22:03:14 +0700 Subject: [PATCH] refact: optimize and refact bg box animate --- app/components/ui/background-boxes.tsx | 111 +++++++++++++++++++++---- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/app/components/ui/background-boxes.tsx b/app/components/ui/background-boxes.tsx index d0f4259..2eec716 100644 --- a/app/components/ui/background-boxes.tsx +++ b/app/components/ui/background-boxes.tsx @@ -1,33 +1,95 @@ -"use client"; -import React from "react"; +import React, { useState, useEffect } from "react"; import { motion } from "motion/react"; import { cn } from "~/lib/utils"; export const BoxesCore = ({ className, ...rest }: { className?: string }) => { const rows = new Array(150).fill(1); const cols = new Array(100).fill(1); - let colors = [ - "#93c5fd", - "#f9a8d4", - "#86efac", - "#fde047", - "#fca5a5", - "#d8b4fe", - "#93c5fd", - "#a5b4fc", - "#c4b5fd" + const [isDarkMode, setIsDarkMode] = useState(false); + + useEffect(() => { + const checkTheme = () => { + const isDark = document.documentElement.classList.contains("dark"); + setIsDarkMode(isDark); + }; + + checkTheme(); + + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if ( + mutation.type === "attributes" && + mutation.attributeName === "class" + ) { + checkTheme(); + } + }); + }); + + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ["class"] + }); + + return () => observer.disconnect(); + }, []); + + const lightModeColors = [ + "rgb(59 130 246)", + "rgb(236 72 153)", + "rgb(16 185 129)", + "rgb(245 158 11)", + "rgb(239 68 68)", + "rgb(139 92 246)", + "rgb(99 102 241)", + "rgb(168 85 247)", + "rgb(6 182 212)" ]; + + const darkModeColors = [ + "rgb(30 58 138)", + "rgb(190 24 93)", + "rgb(22 101 52)", + "rgb(146 64 14)", + "rgb(153 27 27)", + "rgb(124 58 237)", + "rgb(55 48 163)", + "rgb(107 33 168)", + "rgb(22 78 99)" + ]; + const getRandomColor = () => { + const colors = isDarkMode ? darkModeColors : lightModeColors; return colors[Math.floor(Math.random() * colors.length)]; }; + // Theme-aware styles + const getThemeStyles = () => { + if (isDarkMode) { + return { + borderColor: "rgba(71, 85, 105, 0.3)", + strokeColor: "rgba(71, 85, 105, 0.4)", + backgroundColor: "rgba(15, 23, 42, 0.1)" + }; + } else { + return { + borderColor: "rgba(148, 163, 184, 0.2)", + strokeColor: "rgba(100, 116, 139, 0.3)", + backgroundColor: "rgba(248, 250, 252, 0.1)" + }; + } + }; + + const themeStyles = getThemeStyles(); + return (
{ {rows.map((_, i) => ( {cols.map((_, j) => ( { transition: { duration: 2 } }} key={`col` + j} - className="relative h-8 w-16 border-t border-r border-slate-700" + className="relative h-8 w-16" + style={{ + borderTop: `1px solid ${themeStyles.borderColor}`, + borderRight: `1px solid ${themeStyles.borderColor}`, + transition: "border-color 0.3s ease" + }} > {j % 2 === 0 && i % 2 === 0 ? ( { fill="none" viewBox="0 0 24 24" strokeWidth="1.5" - stroke="currentColor" - className="pointer-events-none absolute -top-[14px] -left-[22px] h-6 w-10 stroke-[1px] text-slate-700" + stroke={themeStyles.strokeColor} + className="pointer-events-none absolute -top-[14px] -left-[22px] h-6 w-10 stroke-[1px] transition-colors duration-300" + style={{ + stroke: themeStyles.strokeColor, + transition: "stroke 0.3s ease" + }} >