import { useRef, useState } from 'react'; import { Canvas, useFrame, ThreeEvent } from '@react-three/fiber'; import { Sphere, MeshDistortMaterial, Float } from '@react-three/drei'; import * as THREE from 'three'; interface OrbProps { position?: [number, number, number]; onInteraction?: (type: 'hover' | 'click') => void; } function Orb({ position = [0, 0, 0], onInteraction }: OrbProps) { const meshRef = useRef(null); const [hovered, setHovered] = useState(false); const [clicked, setClicked] = useState(false); useFrame((state) => { if (meshRef.current) { // Continuous rotation meshRef.current.rotation.x = Math.sin(state.clock.elapsedTime * 0.5) * 0.3; meshRef.current.rotation.y = state.clock.elapsedTime * 0.3; // Scale based on interaction const targetScale = clicked ? 1.3 : hovered ? 1.1 : 1; meshRef.current.scale.lerp(new THREE.Vector3(targetScale, targetScale, targetScale), 0.1); } }); const handlePointerOver = (event: ThreeEvent) => { event.stopPropagation(); setHovered(true); onInteraction?.('hover'); }; const handlePointerOut = () => { setHovered(false); }; const handleClick = (event: ThreeEvent) => { event.stopPropagation(); setClicked(true); setTimeout(() => setClicked(false), 200); onInteraction?.('click'); }; return ( ); } interface InteractiveOrbProps { onInteraction?: (type: 'hover' | 'click') => void; className?: string; } export default function InteractiveOrb({ onInteraction, className = "" }: InteractiveOrbProps) { return (
); }