refactor: adjust nebula target, fix initial visibility, and update bento images

This commit is contained in:
jwinterm
2026-01-16 10:42:49 -05:00
parent 782ea2b6ce
commit 51cfd7a3c8
3 changed files with 26 additions and 21 deletions
@@ -6,13 +6,6 @@ import { useEffect, useState } from "react";
export function DynamicBackground() {
const { theme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) return null;
return (
<NebulaField
@@ -10,12 +10,12 @@ export const PortfolioGrid = () => {
<h3 className="text-3xl font-bold text-white shadow-black drop-shadow-xl">r/CryptoCurrency</h3>
<p className="text-gray-200 shadow-black drop-shadow-md max-w-sm mt-2 font-medium">Governance dashboard for 10M+ members. Real-time DAO metrics.</p>
</div>
<div className="absolute inset-x-4 inset-y-4 rounded-lg overflow-hidden z-10">
<div className="absolute inset-4 rounded-xl overflow-hidden z-10 bg-slate-800/50">
<Image
src="/images/r-cryptocurrency.png"
alt="r/CryptoCurrency"
fill
className="object-cover object-top opacity-60 transition-transform duration-1000 group-hover:scale-110"
className="object-contain p-4 opacity-70 transition-transform duration-1000 group-hover:scale-105"
sizes="(max-width: 768px) 100vw, 50vw"
/>
</div>
@@ -27,12 +27,12 @@ export const PortfolioGrid = () => {
<h3 className="text-2xl font-bold text-zinc-900 drop-shadow-sm bg-white/60 backdrop-blur-md rounded-xl px-6 py-2">Occupy Wallets</h3>
<p className="text-zinc-900 font-bold drop-shadow-sm bg-white/60 backdrop-blur-md rounded-xl px-6 py-2 mt-4">High-fidelity gallery for fiscal graffiti.</p>
</div>
<div className="absolute inset-x-4 inset-y-4 rounded-lg overflow-hidden z-10">
<div className="absolute inset-4 rounded-xl overflow-hidden z-10 bg-zinc-200/50">
<Image
src="/images/occupy-wallets.png"
alt="Occupy Wallets"
fill
className="object-cover object-top opacity-50 transition-transform duration-1000 group-hover:scale-110"
className="object-contain p-4 opacity-60 transition-transform duration-1000 group-hover:scale-105"
sizes="(max-width: 768px) 100vw, 50vw"
/>
</div>
@@ -47,12 +47,12 @@ export const PortfolioGrid = () => {
<li className="flex items-center gap-2">Wowne.ro <span className="text-xs opacity-60">(WASM)</span></li>
</ul>
</div>
<div className="absolute inset-x-4 bottom-4 top-24 rounded-lg overflow-hidden z-10 border border-orange-500/20 shadow-lg">
<div className="absolute inset-x-4 bottom-4 top-24 rounded-lg overflow-hidden z-10 bg-black/5 dark:bg-white/5 border border-orange-500/10 shadow-inner">
<Image
src="/images/privacy-labs.png"
alt="Privacy Labs"
fill
className="object-cover object-top opacity-40 transition-transform duration-1000 group-hover:scale-110"
className="object-contain p-2 opacity-50 transition-transform duration-1000 group-hover:scale-110"
sizes="(max-width: 768px) 100vw, 25vw"
/>
</div>
@@ -64,12 +64,12 @@ export const PortfolioGrid = () => {
<h3 className="text-xl font-bold text-indigo-700 dark:text-indigo-400">MoonPlace</h3>
<p className="text-sm mt-1 text-foreground font-semibold">Collaborative pixel canvas engine.</p>
</div>
<div className="absolute inset-x-4 bottom-4 top-24 rounded-lg overflow-hidden z-10 border border-indigo-500/20 shadow-lg">
<div className="absolute inset-x-4 bottom-4 top-24 rounded-lg overflow-hidden z-10 bg-black/5 dark:bg-white/5 border border-indigo-500/10 shadow-inner">
<Image
src="/images/moonplace.png"
alt="MoonPlace"
fill
className="object-cover object-top opacity-40 transition-transform duration-1000 group-hover:scale-110"
className="object-contain p-2 opacity-50 transition-transform duration-1000 group-hover:scale-110"
sizes="(max-width: 768px) 100vw, 25vw"
/>
</div>
+18 -6
View File
@@ -24,11 +24,11 @@ const StreamLine = ({ d, themeMode, onHit, width }: StreamLineProps) => {
useEffect(() => {
let isMounted = true;
const animate = async () => {
// Staggered start delay (0-4s)
await new Promise(resolve => setTimeout(resolve, Math.random() * 4000));
// Shorter start delay (0-2s) so it feels more reactive on load
await new Promise(resolve => setTimeout(resolve, Math.random() * 2000));
while (isMounted) {
const duration = 10 + Math.random() * 8; // Slow streamers
const duration = 8 + Math.random() * 6; // slightly faster but still slow
// Ensure starting state is definitely 0
controls.set({ pathLength: 0, pathOffset: 0, opacity: 0 });
@@ -91,7 +91,7 @@ export const NebulaField = ({ className, density = 8, themeMode = 'dark' }: Nebu
// Configuration for convergence point
const targetX = 25;
const targetY = 20;
const targetY = 30; // Lowered to hit center of computer better
const paths = useMemo(() => {
return Array.from({ length: density }).map(() => {
@@ -118,6 +118,18 @@ export const NebulaField = ({ className, density = 8, themeMode = 'dark' }: Nebu
setMounted(true);
}, []);
// Initial animation for the computer icon
useEffect(() => {
if (mounted) {
monitorControls.set({ opacity: 0, scale: 0.5 });
monitorControls.start({
opacity: themeMode === 'light' ? 0.4 : 0.6,
scale: 1,
transition: { duration: 2, ease: "easeOut" }
});
}
}, [mounted, themeMode, monitorControls]);
const handleHit = useCallback(() => {
const colors = [
"text-emerald-500", "text-blue-500", "text-purple-500",
@@ -142,7 +154,7 @@ export const NebulaField = ({ className, density = 8, themeMode = 'dark' }: Nebu
<div className={cn("absolute inset-0 overflow-hidden pointer-events-none z-0", className)}>
<motion.div
className="absolute -translate-x-1/2 -translate-y-1/2 z-20 opacity-40 dark:opacity-60"
className="absolute -translate-x-1/2 -translate-y-1/2 z-20"
style={{
left: `${targetX}%`,
top: `${targetY}%`,
@@ -170,7 +182,7 @@ export const NebulaField = ({ className, density = 8, themeMode = 'dark' }: Nebu
d={d}
themeMode={themeMode}
onHit={handleHit}
width={themeMode === 'light' ? 0.05 : 0.15}
width={themeMode === 'light' ? 0.1 : 0.2}
/>
))}
</svg>