File size: 2,715 Bytes
5008b66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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<THREE.Mesh>(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<PointerEvent>) => {
    event.stopPropagation();
    setHovered(true);
    onInteraction?.('hover');
  };

  const handlePointerOut = () => {
    setHovered(false);
  };

  const handleClick = (event: ThreeEvent<MouseEvent>) => {
    event.stopPropagation();
    setClicked(true);
    setTimeout(() => setClicked(false), 200);
    onInteraction?.('click');
  };

  return (
    <Float speed={1.5} rotationIntensity={0.3} floatIntensity={0.5}>
      <Sphere
        ref={meshRef}
        args={[1]}
        position={position}
        onPointerOver={handlePointerOver}
        onPointerOut={handlePointerOut}
        onClick={handleClick}
      >
        <MeshDistortMaterial
          color={clicked ? "#ec4899" : hovered ? "#06b6d4" : "#a855f7"}
          transparent
          opacity={0.8}
          distort={hovered ? 0.6 : 0.3}
          speed={clicked ? 5 : hovered ? 3 : 1}
          emissive={clicked ? "#db2777" : hovered ? "#0891b2" : "#8b5cf6"}
          emissiveIntensity={clicked ? 0.8 : hovered ? 0.5 : 0.2}
        />
      </Sphere>
    </Float>
  );
}

interface InteractiveOrbProps {
  onInteraction?: (type: 'hover' | 'click') => void;
  className?: string;
}

export default function InteractiveOrb({ onInteraction, className = "" }: InteractiveOrbProps) {
  return (
    <div className={`w-full h-full cursor-pointer ${className}`}>
      <Canvas camera={{ position: [0, 0, 5], fov: 45 }}>
        <ambientLight intensity={0.4} />
        <directionalLight position={[10, 10, 5]} intensity={1} />
        <pointLight position={[-10, -10, -5]} intensity={0.5} color="#a855f7" />
        
        <Orb onInteraction={onInteraction} />
      </Canvas>
    </div>
  );
}