Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 11s
Build & Deploy / 🧪 QA (push) Successful in 1m18s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled
CI - Lint, Typecheck & Test / quality-assurance (pull_request) Failing after 3m55s
89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
/* eslint-disable react/no-unknown-property */
|
|
'use client';
|
|
|
|
import React, { useRef } from 'react';
|
|
import { Canvas, useFrame } from '@react-three/fiber';
|
|
import { Sphere, MeshDistortMaterial, Environment, Float } from '@react-three/drei';
|
|
import * as THREE from 'three';
|
|
|
|
interface AIOrbProps {
|
|
isThinking: boolean;
|
|
}
|
|
|
|
function Orb({ isThinking }: AIOrbProps) {
|
|
const meshRef = useRef<THREE.Mesh>(null);
|
|
const materialRef = useRef<any>(null);
|
|
|
|
// Dynamic properties based on state
|
|
const targetDistort = isThinking ? 0.6 : 0.3;
|
|
const targetSpeed = isThinking ? 5 : 2;
|
|
const color = isThinking ? '#00FF88' : '#00A3FF'; // Green/Blue based on thinking state
|
|
|
|
useFrame((state) => {
|
|
if (!materialRef.current) return;
|
|
|
|
// Smoothly interpolate material properties
|
|
materialRef.current.distort = THREE.MathUtils.lerp(
|
|
materialRef.current.distort,
|
|
targetDistort,
|
|
0.1,
|
|
);
|
|
materialRef.current.speed = THREE.MathUtils.lerp(materialRef.current.speed, targetSpeed, 0.1);
|
|
|
|
// Smooth color transition
|
|
const currentColor = materialRef.current.color;
|
|
const targetColorObj = new THREE.Color(color);
|
|
currentColor.lerp(targetColorObj, 0.05);
|
|
|
|
// Slow rotation
|
|
if (meshRef.current) {
|
|
meshRef.current.rotation.x = state.clock.getElapsedTime() * 0.2;
|
|
meshRef.current.rotation.y = state.clock.getElapsedTime() * 0.3;
|
|
}
|
|
});
|
|
|
|
return (
|
|
<Float
|
|
speed={isThinking ? 4 : 2}
|
|
rotationIntensity={isThinking ? 2 : 1}
|
|
floatIntensity={isThinking ? 2 : 1}
|
|
>
|
|
<Sphere ref={meshRef} args={[1, 64, 64]} scale={1.5}>
|
|
<MeshDistortMaterial
|
|
ref={materialRef}
|
|
color="#00A3FF"
|
|
envMapIntensity={2}
|
|
clearcoat={1}
|
|
clearcoatRoughness={0}
|
|
metalness={0.8}
|
|
roughness={0.1}
|
|
distort={0.3}
|
|
speed={2}
|
|
/>
|
|
</Sphere>
|
|
</Float>
|
|
);
|
|
}
|
|
|
|
export default function AIOrb({ isThinking = false }: AIOrbProps) {
|
|
return (
|
|
<div className="w-full h-full min-w-[32px] min-h-[32px] relative flex items-center justify-center">
|
|
{/* Ambient glow effect behind the orb */}
|
|
<div
|
|
className={`absolute inset-0 rounded-full blur-xl opacity-50 transition-colors duration-1000 ${isThinking ? 'bg-[#00FF88]/50' : 'bg-[#00A3FF]/40'}`}
|
|
/>
|
|
|
|
<Canvas
|
|
camera={{ position: [0, 0, 4], fov: 45 }}
|
|
className="w-full h-full cursor-pointer z-10 block"
|
|
>
|
|
<ambientLight intensity={0.5} />
|
|
<directionalLight position={[10, 10, 5]} intensity={1.5} />
|
|
<directionalLight position={[-10, -10, -5]} intensity={0.5} color="#00FF88" />
|
|
<Orb isThinking={isThinking} />
|
|
<Environment preset="city" />
|
|
</Canvas>
|
|
</div>
|
|
);
|
|
}
|