Initial commit gov-llm-v2
This commit is contained in:
166
components/TechVisualizer.tsx
Executable file
166
components/TechVisualizer.tsx
Executable file
@@ -0,0 +1,166 @@
|
||||
|
||||
import React, { useRef, useMemo, useEffect } from 'react';
|
||||
import { Canvas, useFrame } from '@react-three/fiber';
|
||||
import { OrbitControls, PerspectiveCamera } from '@react-three/drei';
|
||||
import * as THREE from 'three';
|
||||
|
||||
// Add global declaration to fix TypeScript errors with React Three Fiber elements
|
||||
declare module 'react' {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
points: any;
|
||||
bufferGeometry: any;
|
||||
bufferAttribute: any;
|
||||
pointsMaterial: any;
|
||||
ambientLight: any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
points: any;
|
||||
bufferGeometry: any;
|
||||
bufferAttribute: any;
|
||||
pointsMaterial: any;
|
||||
ambientLight: any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface TechVisualizerProps {
|
||||
mode: 'server' | 'monitor' | 'hidden';
|
||||
}
|
||||
|
||||
const ParticleMorph = ({ mode }: { mode: 'server' | 'monitor' | 'hidden' }) => {
|
||||
const meshRef = useRef<THREE.Points>(null);
|
||||
const COUNT = 3000;
|
||||
|
||||
// Define geometries
|
||||
const data = useMemo(() => {
|
||||
const pos = new Float32Array(COUNT * 3);
|
||||
const col = new Float32Array(COUNT * 3);
|
||||
const serverPos = new Float32Array(COUNT * 3);
|
||||
const monitorPos = new Float32Array(COUNT * 3);
|
||||
|
||||
// SERVER SHAPE (Rectangular Tower)
|
||||
for (let i = 0; i < COUNT; i++) {
|
||||
const x = (Math.random() - 0.5) * 2; // Thin width
|
||||
const y = (Math.random() - 0.5) * 6; // Tall
|
||||
const z = (Math.random() - 0.5) * 2; // Depth
|
||||
|
||||
serverPos[i * 3] = x;
|
||||
serverPos[i * 3 + 1] = y;
|
||||
serverPos[i * 3 + 2] = z;
|
||||
|
||||
// Add some "layers" to make it look like a rack
|
||||
if (Math.random() > 0.8) {
|
||||
serverPos[i * 3] *= 1.2;
|
||||
serverPos[i * 3 + 2] *= 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
// MONITOR SHAPE (Curved Plane)
|
||||
for (let i = 0; i < COUNT; i++) {
|
||||
const x = (Math.random() - 0.5) * 8; // Wide
|
||||
const y = (Math.random() - 0.5) * 3.5; // Aspect ratio
|
||||
// Curve the Z based on X (parabolic)
|
||||
const z = Math.pow(x * 0.3, 2) - 2;
|
||||
|
||||
monitorPos[i * 3] = x;
|
||||
monitorPos[i * 3 + 1] = y + 0.5; // Lift up slightly
|
||||
monitorPos[i * 3 + 2] = z;
|
||||
|
||||
// Bezel/Frame particles
|
||||
if (Math.random() > 0.95) {
|
||||
monitorPos[i * 3 + 2] += 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
// Initial Positions (start at server)
|
||||
for (let i = 0; i < COUNT * 3; i++) {
|
||||
pos[i] = serverPos[i];
|
||||
col[i] = 1; // Initial white/cyan mix logic in shader or simple color
|
||||
}
|
||||
|
||||
return { positions: pos, colors: col, serverPos, monitorPos };
|
||||
}, []);
|
||||
|
||||
// Buffer attributes
|
||||
const bufferRef = useRef<THREE.BufferAttribute>(null);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
if (!meshRef.current || !bufferRef.current) return;
|
||||
|
||||
const target = mode === 'monitor' ? data.monitorPos : data.serverPos;
|
||||
const current = bufferRef.current.array as Float32Array;
|
||||
|
||||
// Morph speed
|
||||
const speed = 4 * delta;
|
||||
|
||||
// Visibility transition
|
||||
const isHidden = mode === 'hidden';
|
||||
|
||||
for (let i = 0; i < COUNT; i++) {
|
||||
const ix = i * 3;
|
||||
const iy = i * 3 + 1;
|
||||
const iz = i * 3 + 2;
|
||||
|
||||
if (isHidden) {
|
||||
// Explode/Hide
|
||||
current[ix] = THREE.MathUtils.lerp(current[ix], current[ix] * 1.01, speed);
|
||||
current[iy] = THREE.MathUtils.lerp(current[iy], current[iy] + 10, speed);
|
||||
} else {
|
||||
// Standard Morph
|
||||
current[ix] = THREE.MathUtils.lerp(current[ix], target[ix], speed);
|
||||
current[iy] = THREE.MathUtils.lerp(current[iy], target[iy], speed);
|
||||
current[iz] = THREE.MathUtils.lerp(current[iz], target[iz], speed);
|
||||
|
||||
// Add subtle noise/floating
|
||||
current[iy] += Math.sin(state.clock.elapsedTime + current[ix]) * 0.002;
|
||||
}
|
||||
}
|
||||
|
||||
bufferRef.current.needsUpdate = true;
|
||||
|
||||
// Rotate entire mesh slowly
|
||||
meshRef.current.rotation.y += delta * 0.1;
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={meshRef}>
|
||||
<bufferGeometry>
|
||||
<bufferAttribute
|
||||
ref={bufferRef}
|
||||
attach="attributes-position"
|
||||
array={data.positions}
|
||||
count={data.positions.length / 3}
|
||||
itemSize={3}
|
||||
/>
|
||||
</bufferGeometry>
|
||||
<pointsMaterial
|
||||
size={0.04}
|
||||
color={mode === 'monitor' ? "#ff4b4b" : "#20e3b2"} // Red for monitor (Anime.js accent), Cyan for Server
|
||||
transparent
|
||||
opacity={0.8}
|
||||
sizeAttenuation
|
||||
blending={THREE.AdditiveBlending}
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
};
|
||||
|
||||
const TechVisualizer: React.FC<TechVisualizerProps> = ({ mode }) => {
|
||||
return (
|
||||
<div className={`fixed inset-0 z-[1] transition-opacity duration-700 pointer-events-none ${mode === 'hidden' ? 'opacity-0' : 'opacity-60'}`}>
|
||||
<Canvas gl={{ antialias: true, alpha: true }}>
|
||||
<PerspectiveCamera makeDefault position={[0, 0, 8]} fov={50} />
|
||||
<ambientLight intensity={0.5} />
|
||||
<ParticleMorph mode={mode} />
|
||||
</Canvas>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TechVisualizer;
|
||||
Reference in New Issue
Block a user