All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 27s
Build & Deploy / 🚀 Deploy (push) Successful in 34s
Build & Deploy / 🧪 QA (push) Successful in 1m46s
Build & Deploy / 🏗️ Build (push) Successful in 3m38s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m19s
Build & Deploy / 🔔 Notify (push) Successful in 5s
189 lines
7.0 KiB
TypeScript
189 lines
7.0 KiB
TypeScript
'use client';
|
|
|
|
import React, { useRef, useEffect } from 'react';
|
|
import { useScroll, useTransform, useSpring, m } from 'framer-motion';
|
|
import { LogoArcs } from '@/components/ui/LogoArcs';
|
|
|
|
function MagneticRing({
|
|
children,
|
|
className,
|
|
pullStrength = 30, // How strong the pull is (higher = moves closer to mouse)
|
|
pullRadius = 600 // Distance from center at which it starts pulling
|
|
}: {
|
|
children: React.ReactNode,
|
|
className?: string,
|
|
pullStrength?: number,
|
|
pullRadius?: number
|
|
}) {
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
|
// Spring physics for extremely smooth, organic movement
|
|
const x = useSpring(0, { stiffness: 40, damping: 25, mass: 1 });
|
|
const y = useSpring(0, { stiffness: 40, damping: 25, mass: 1 });
|
|
|
|
useEffect(() => {
|
|
// Only run on client with mouse
|
|
if (window.matchMedia("(pointer: coarse)").matches) return;
|
|
|
|
const handleMouseMove = (e: MouseEvent) => {
|
|
if (!ref.current) return;
|
|
const rect = ref.current.getBoundingClientRect();
|
|
const centerX = rect.left + rect.width / 2;
|
|
const centerY = rect.top + rect.height / 2;
|
|
|
|
const distX = e.clientX - centerX;
|
|
const distY = e.clientY - centerY;
|
|
const distance = Math.sqrt(distX * Math.pow(distX, 2) + Math.pow(distY, 2)); // Fix: correct pythagoras
|
|
|
|
// Calculate actual distance correctly
|
|
const actualDistance = Math.sqrt(distX * distX + distY * distY);
|
|
|
|
if (actualDistance < pullRadius) {
|
|
// Exponential falloff for natural magnetic feel
|
|
const pullFactor = Math.pow(1 - (actualDistance / pullRadius), 2);
|
|
|
|
// Target offset (fraction of the distance based on strength)
|
|
x.set(distX * pullFactor * (pullStrength / 100));
|
|
y.set(distY * pullFactor * (pullStrength / 100));
|
|
} else {
|
|
// Return to origin smoothly
|
|
x.set(0);
|
|
y.set(0);
|
|
}
|
|
};
|
|
|
|
window.addEventListener('mousemove', handleMouseMove);
|
|
return () => window.removeEventListener('mousemove', handleMouseMove);
|
|
}, [x, y, pullRadius, pullStrength]);
|
|
|
|
return (
|
|
<m.div
|
|
ref={ref}
|
|
style={{ x, y }}
|
|
className={className}
|
|
>
|
|
{children}
|
|
</m.div>
|
|
);
|
|
}
|
|
|
|
export function CorporateBackground() {
|
|
const { scrollYProgress } = useScroll();
|
|
|
|
// Stronger parallax offsets for visible movement
|
|
const y1 = useTransform(scrollYProgress, [0, 1], [0, -400]);
|
|
const y2 = useTransform(scrollYProgress, [0, 1], [0, 500]);
|
|
const y3 = useTransform(scrollYProgress, [0, 1], [0, -600]);
|
|
const y4 = useTransform(scrollYProgress, [0, 1], [0, 350]);
|
|
const y5 = useTransform(scrollYProgress, [0, 1], [0, -500]);
|
|
|
|
return (
|
|
<div className="absolute inset-0 z-[50] overflow-hidden pointer-events-none hidden md:block" aria-hidden="true">
|
|
{/* 1. Top Right - Medium, rotating moderately */}
|
|
<m.div
|
|
style={{
|
|
y: y1,
|
|
animationDelay: '0s',
|
|
maskImage: 'radial-gradient(circle at center, black 10%, transparent 60%)',
|
|
WebkitMaskImage: 'radial-gradient(circle at center, black 10%, transparent 60%)'
|
|
}}
|
|
className="absolute top-[0%] right-0 translate-x-[40%] w-[400px] h-[400px] md:w-[700px] md:h-[700px] animate-bg-pulse-20"
|
|
>
|
|
<MagneticRing pullRadius={700} pullStrength={40} className="w-full h-full">
|
|
<m.div
|
|
animate={{ rotate: 360 }}
|
|
transition={{ duration: 40, repeat: Infinity, ease: "linear" }}
|
|
className="w-full h-full text-primary"
|
|
>
|
|
<LogoArcs className="w-full h-full" />
|
|
</m.div>
|
|
</MagneticRing>
|
|
</m.div>
|
|
|
|
{/* 2. Quarter way down left - Smaller, rotating fast reverse */}
|
|
<m.div
|
|
style={{
|
|
y: y2,
|
|
animationDelay: '3s',
|
|
maskImage: 'radial-gradient(circle at center, black 15%, transparent 65%)',
|
|
WebkitMaskImage: 'radial-gradient(circle at center, black 15%, transparent 65%)'
|
|
}}
|
|
className="absolute top-[20%] left-0 -translate-x-[40%] w-[300px] h-[300px] md:w-[500px] md:h-[500px] animate-bg-pulse-15"
|
|
>
|
|
<MagneticRing pullRadius={500} pullStrength={50} className="w-full h-full">
|
|
<m.div
|
|
animate={{ rotate: -360 }}
|
|
transition={{ duration: 30, repeat: Infinity, ease: "linear" }}
|
|
className="w-full h-full text-secondary"
|
|
>
|
|
<LogoArcs className="w-full h-full -rotate-45" />
|
|
</m.div>
|
|
</MagneticRing>
|
|
</m.div>
|
|
|
|
{/* 3. Halfway down right - Medium, rotating slow */}
|
|
<m.div
|
|
style={{
|
|
y: y3,
|
|
animationDelay: '6s',
|
|
maskImage: 'radial-gradient(circle at center, black 10%, transparent 60%)',
|
|
WebkitMaskImage: 'radial-gradient(circle at center, black 10%, transparent 60%)'
|
|
}}
|
|
className="absolute top-[45%] right-0 translate-x-[30%] w-[350px] h-[350px] md:w-[600px] md:h-[600px] animate-bg-pulse-15"
|
|
>
|
|
<MagneticRing pullRadius={600} pullStrength={35} className="w-full h-full">
|
|
<m.div
|
|
animate={{ rotate: 360 }}
|
|
transition={{ duration: 60, repeat: Infinity, ease: "linear" }}
|
|
className="w-full h-full text-primary"
|
|
>
|
|
<LogoArcs className="w-full h-full rotate-90" />
|
|
</m.div>
|
|
</MagneticRing>
|
|
</m.div>
|
|
|
|
{/* 4. Bottom left - Larger, rotating moderately */}
|
|
<m.div
|
|
style={{
|
|
y: y4,
|
|
animationDelay: '9s',
|
|
maskImage: 'radial-gradient(circle at center, black 5%, transparent 60%)',
|
|
WebkitMaskImage: 'radial-gradient(circle at center, black 5%, transparent 60%)'
|
|
}}
|
|
className="absolute top-[70%] left-0 -translate-x-[40%] w-[500px] h-[500px] md:w-[800px] md:h-[800px] animate-bg-pulse-20"
|
|
>
|
|
<MagneticRing pullRadius={800} pullStrength={30} className="w-full h-full">
|
|
<m.div
|
|
animate={{ rotate: -360 }}
|
|
transition={{ duration: 50, repeat: Infinity, ease: "linear" }}
|
|
className="w-full h-full text-secondary"
|
|
>
|
|
<LogoArcs className="w-full h-full rotate-180" />
|
|
</m.div>
|
|
</MagneticRing>
|
|
</m.div>
|
|
|
|
{/* 5. Deep bottom right - Smallest, very fast */}
|
|
<m.div
|
|
style={{
|
|
y: y5,
|
|
animationDelay: '12s',
|
|
maskImage: 'radial-gradient(circle at center, black 20%, transparent 70%)',
|
|
WebkitMaskImage: 'radial-gradient(circle at center, black 20%, transparent 70%)'
|
|
}}
|
|
className="absolute top-[88%] right-0 translate-x-[50%] w-[250px] h-[250px] md:w-[400px] md:h-[400px] animate-bg-pulse-15"
|
|
>
|
|
<MagneticRing pullRadius={400} pullStrength={60} className="w-full h-full">
|
|
<m.div
|
|
animate={{ rotate: 360 }}
|
|
transition={{ duration: 25, repeat: Infinity, ease: "linear" }}
|
|
className="w-full h-full text-primary"
|
|
>
|
|
<LogoArcs className="w-full h-full -rotate-12" />
|
|
</m.div>
|
|
</MagneticRing>
|
|
</m.div>
|
|
</div>
|
|
);
|
|
}
|