website-monitor/frontend/components/landing/BackgroundEffects.tsx

113 lines
4.9 KiB
TypeScript

'use client'
import { motion } from 'framer-motion'
import { useEffect, useState } from 'react'
export function BackgroundGradient() {
return (
<div className="fixed inset-0 -z-30 overflow-hidden pointer-events-none">
<div
className="absolute inset-x-0 -top-40 -z-30 transform-gpu overflow-hidden blur-3xl sm:-top-80"
aria-hidden="true"
>
<div
className="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[hsl(var(--primary))] to-[hsl(var(--teal))] opacity-20 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div>
<div
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-30 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
aria-hidden="true"
>
<div
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[hsl(var(--burgundy))] to-[hsl(var(--primary))] opacity-20 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
style={{
clipPath:
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
}}
/>
</div>
</div>
)
}
export function FloatingElements() {
return (
<div className="fixed inset-0 -z-20 pointer-events-none overflow-hidden">
{[...Array(6)].map((_, i) => (
<motion.div
key={i}
className="absolute h-64 w-64 rounded-full bg-gradient-to-br from-primary/5 to-transparent blur-3xl"
animate={{
x: [Math.random() * 100 + '%', Math.random() * 100 + '%'],
y: [Math.random() * 100 + '%', Math.random() * 100 + '%'],
scale: [1, 1.2, 1],
opacity: [0.3, 0.5, 0.3],
}}
transition={{
duration: 20 + Math.random() * 10,
repeat: Infinity,
ease: "linear",
}}
style={{
left: Math.random() * 100 + '%',
top: Math.random() * 100 + '%',
}}
/>
))}
</div>
)
}
export function InteractiveGrid() {
const [mousePos, setMousePos] = useState({ x: 0, y: 0 })
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
setMousePos({ x: e.clientX, y: e.clientY })
}
window.addEventListener('mousemove', handleMouseMove)
return () => window.removeEventListener('mousemove', handleMouseMove)
}, [])
return (
<div className="fixed inset-0 -z-30 pointer-events-none">
<div
className="absolute inset-0 bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:40px_40px]"
/>
<div
className="absolute inset-0 bg-gradient-to-t from-background via-transparent to-transparent"
/>
<motion.div
className="absolute inset-0 bg-[radial-gradient(600px_at_var(--x)_var(--y),hsl(var(--primary)/0.08),transparent_80%)]"
style={{
// @ts-ignore
'--x': mousePos.x + 'px',
'--y': mousePos.y + 'px',
}}
/>
</div>
)
}
export function GlowEffect() {
return (
<div className="fixed inset-0 -z-20 pointer-events-none">
<div className="absolute top-0 left-1/4 w-96 h-96 bg-primary/10 rounded-full blur-[120px] mix-blend-screen" />
<div className="absolute bottom-0 right-1/4 w-96 h-96 bg-teal/10 rounded-full blur-[120px] mix-blend-screen" />
</div>
)
}
export function SectionDivider() {
return (
<div className="relative h-px w-full">
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-border to-transparent" />
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-primary/20 to-transparent blur-sm" />
</div>
)
}