feat: add robotics components and data structures
- Introduced RobotProductCard component for displaying robot details. - Added WhyUs component highlighting key reasons for choosing our robotics solutions. - Implemented CursorSpotlight for enhanced user interaction. - Created GlassPanel for a stylish UI element. - Developed MotionSection for animated section visibility. - Added PremiumButton for versatile button options. - Established data structures for industries and robots, including detailed specifications and use cases. - Included utility functions for retrieving robots by slug and category.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
type Props = {
|
||||
color?: string;
|
||||
size?: number;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function CursorSpotlight({ color = 'rgba(196, 162, 101, 0.18)', size = 520, className = '' }: Props) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
const [pos, setPos] = useState<{ x: number; y: number } | null>(null);
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const finePointer = window.matchMedia('(pointer: fine)').matches;
|
||||
const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
if (!finePointer || reduced) return;
|
||||
setEnabled(true);
|
||||
|
||||
const el = ref.current?.parentElement;
|
||||
if (!el) return;
|
||||
let raf = 0;
|
||||
const onMove = (e: MouseEvent) => {
|
||||
const rect = el.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
cancelAnimationFrame(raf);
|
||||
raf = requestAnimationFrame(() => setPos({ x, y }));
|
||||
};
|
||||
const onLeave = () => setPos(null);
|
||||
el.addEventListener('mousemove', onMove);
|
||||
el.addEventListener('mouseleave', onLeave);
|
||||
return () => {
|
||||
el.removeEventListener('mousemove', onMove);
|
||||
el.removeEventListener('mouseleave', onLeave);
|
||||
cancelAnimationFrame(raf);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!enabled) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
aria-hidden
|
||||
className={className}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
pointerEvents: 'none',
|
||||
opacity: pos ? 1 : 0,
|
||||
transition: 'opacity 0.4s ease',
|
||||
background: pos
|
||||
? `radial-gradient(${size}px ${size}px at ${pos.x}px ${pos.y}px, ${color}, transparent 70%)`
|
||||
: 'transparent',
|
||||
zIndex: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user