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

121 lines
3.3 KiB
TypeScript

'use client'
import { motion, useMotionValue, useSpring, useTransform } from 'framer-motion'
import { useRef, ReactNode } from 'react'
interface MagneticButtonProps {
children: ReactNode
className?: string
onClick?: () => void
strength?: number
}
export function MagneticButton({
children,
className = '',
onClick,
strength = 0.3
}: MagneticButtonProps) {
const ref = useRef<HTMLDivElement>(null)
const x = useMotionValue(0)
const y = useMotionValue(0)
const springConfig = { stiffness: 300, damping: 20 }
const springX = useSpring(x, springConfig)
const springY = useSpring(y, springConfig)
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
if (!ref.current) return
const rect = ref.current.getBoundingClientRect()
const centerX = rect.left + rect.width / 2
const centerY = rect.top + rect.height / 2
const deltaX = (e.clientX - centerX) * strength
const deltaY = (e.clientY - centerY) * strength
x.set(deltaX)
y.set(deltaY)
}
const handleMouseLeave = () => {
x.set(0)
y.set(0)
}
return (
<motion.div
ref={ref}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
onClick={onClick}
style={{ x: springX, y: springY }}
className={`inline-block ${className}`}
>
{children}
</motion.div>
)
}
interface SectionDividerProps {
variant?: 'wave' | 'diagonal' | 'curve'
fromColor?: string
toColor?: string
flip?: boolean
}
export function SectionDivider({
variant = 'wave',
fromColor = 'section-bg-3',
toColor = 'section-bg-4',
flip = false
}: SectionDividerProps) {
if (variant === 'wave') {
return (
<div className={`w-full h-20 -mt-1 overflow-hidden ${flip ? 'rotate-180' : ''}`}>
<svg
viewBox="0 0 1200 120"
preserveAspectRatio="none"
className="w-full h-full"
>
<path
d="M0,0 Q300,80 600,40 T1200,0 L1200,120 L0,120 Z"
fill={`hsl(var(--${toColor}))`}
/>
</svg>
</div>
)
}
if (variant === 'diagonal') {
return (
<div
className={`w-full h-16 ${flip ? '-skew-y-2' : 'skew-y-2'}`}
style={{
background: `linear-gradient(to bottom right, hsl(var(--${fromColor})), hsl(var(--${toColor})))`
}}
/>
)
}
if (variant === 'curve') {
return (
<div className={`w-full h-24 -mt-1 overflow-hidden ${flip ? 'rotate-180' : ''}`}>
<svg
viewBox="0 0 1200 120"
preserveAspectRatio="none"
className="w-full h-full"
>
<path
d="M0,60 Q300,120 600,60 T1200,60 L1200,120 L0,120 Z"
fill={`hsl(var(--${toColor}))`}
/>
</svg>
</div>
)
}
return null
}