diff --git a/app/components/canvas/BioNeurons.tsx b/app/components/canvas/BioNeurons.tsx deleted file mode 100644 index 8592943..0000000 --- a/app/components/canvas/BioNeurons.tsx +++ /dev/null @@ -1,192 +0,0 @@ -"use client"; - -import { useMemo, useRef, useState } from "react"; -import { Canvas, useFrame, useThree } from "@react-three/fiber"; -import { MeshDistortMaterial, Sphere, Preload, Float } from "@react-three/drei"; -import * as THREE from "three"; - -// --- CONFIGURATION --- -const NEURON_COUNT = 18; // Fewer, but more detailed neurons -const CONNECTION_DISTANCE = 5.5; // Distance to form a synapse -const PULSE_SPEED = 2.5; // Speed of the electric signal - -// 1. SINGLE NEURON CELL (The Soma) -// We use a distorted sphere to make it look like organic tissue -function NeuronCell({ position }: { position: [number, number, number] }) { - const meshRef = useRef(null!); - const [hovered, setHover] = useState(false); - - // Randomize size slightly for variety - const scale = useMemo(() => 0.6 + Math.random() * 0.4, []); - - useFrame((state) => { - // Gentle heartbeat pulsation - const t = state.clock.getElapsedTime(); - const pulse = Math.sin(t * 3) * 0.05 + 1; - if (meshRef.current) { - meshRef.current.scale.set(scale * pulse, scale * pulse, scale * pulse); - } - }); - - return ( - - setHover(true)} - onPointerOut={() => setHover(false)} - > - - - - - ); -} - -// 2. SYNAPSE (The Connection & The Impulse) -// Draws a curved organic line and a traveling light pulse -function Synapse({ start, end }: { start: THREE.Vector3; end: THREE.Vector3 }) { - const curve = useMemo(() => { - // Create a quadratic bezier curve for a natural "tendon" look - // Control point is midway but offset randomly to create the curve - const mid = new THREE.Vector3().lerpVectors(start, end, 0.5); - mid.x += (Math.random() - 0.5) * 2; - mid.y += (Math.random() - 0.5) * 2; - mid.z += (Math.random() - 0.5) * 2; - return new THREE.QuadraticBezierCurve3(start, mid, end); - }, [start, end]); - - // Create points for the line geometry - const points = useMemo(() => curve.getPoints(20), [curve]); - - // The traveling impulse ref - const impulseRef = useRef(null!); - - useFrame((state) => { - // Move the impulse along the curve - const t = (state.clock.getElapsedTime() * PULSE_SPEED) % 1; // 0 to 1 loop - if (impulseRef.current) { - const pos = curve.getPointAt(t); - impulseRef.current.position.copy(pos); - - // Scale impulse based on position (fade in/out at ends) - const scale = Math.sin(t * Math.PI); - impulseRef.current.scale.setScalar(scale * 0.15); - } - }); - - return ( - - {/* The Axon (Line) */} - - - [p.x, p.y, p.z]))} - itemSize={3} - /> - - - - - {/* The Electric Impulse (Glowing Dot) */} - - - - - - - ); -} - -// 3. MAIN SCENE CONTROLLER -function NeuralNetworkScene() { - const { viewport } = useThree(); - const mouse = useRef(new THREE.Vector2()); - - // Generate Neurons - const neurons = useMemo(() => { - const temp = []; - for (let i = 0; i < NEURON_COUNT; i++) { - temp.push({ - position: new THREE.Vector3( - (Math.random() - 0.5) * 20, - (Math.random() - 0.5) * 20, - (Math.random() - 0.5) * 10 - ), - id: i, - }); - } - return temp; - }, []); - - // Generate Connections (Proximity based) - const connections = useMemo(() => { - const conns = []; - for (let i = 0; i < neurons.length; i++) { - for (let j = i + 1; j < neurons.length; j++) { - const dist = neurons[i].position.distanceTo(neurons[j].position); - if (dist < CONNECTION_DISTANCE) { - conns.push({ start: neurons[i].position, end: neurons[j].position, key: `${i}-${j}` }); - } - } - } - return conns; - }, [neurons]); - - useFrame((state) => { - // Soft camera movement based on mouse - const x = (state.pointer.x * viewport.width) / 10; - const y = (state.pointer.y * viewport.height) / 10; - - state.camera.position.x = THREE.MathUtils.lerp(state.camera.position.x, x, 0.05); - state.camera.position.y = THREE.MathUtils.lerp(state.camera.position.y, y, 0.05); - state.camera.lookAt(0, 0, 0); - }); - - return ( - - {/* Draw Neurons */} - {neurons.map((n) => ( - - ))} - - {/* Draw Synapses */} - {connections.map((c) => ( - - ))} - - ); -} - -export default function BioNeurons() { - return ( -
- - - - - - -
- ); -} \ No newline at end of file diff --git a/app/components/canvas/NeuronsGravity.tsx b/app/components/canvas/NeuronsGravity.tsx deleted file mode 100644 index 7f2efcc..0000000 --- a/app/components/canvas/NeuronsGravity.tsx +++ /dev/null @@ -1,183 +0,0 @@ -"use client"; - -import { useMemo, useRef } from "react"; -import { Canvas, useFrame, useThree } from "@react-three/fiber"; -import * as THREE from "three"; -import { Preload } from "@react-three/drei"; - -// CONFIGURATION -const PARTICLE_COUNT = 80; -const CONNECT_DISTANCE = 3.5; -const MOUSE_INFLUENCE_RADIUS = 6; // Radius of the mouse wave -const WAVE_AMPLITUDE = 1.5; // How high the wave ripples (Z-axis) - -function NeuralMesh() { - const groupRef = useRef(null); - const particlesRef = useRef(null); - const linesRef = useRef(null); - - // Get viewport to map mouse coordinates correctly to world space - const { viewport } = useThree(); - - // 1. Generate Initial Random Positions & Velocities - // We store "original positions" to calculate the wave offset from - const [positions, velocities, originalPositions] = useMemo(() => { - const pos = new Float32Array(PARTICLE_COUNT * 3); - const origPos = new Float32Array(PARTICLE_COUNT * 3); - const vel = []; - - for (let i = 0; i < PARTICLE_COUNT; i++) { - const x = (Math.random() - 0.5) * 18; - const y = (Math.random() - 0.5) * 18; - const z = (Math.random() - 0.5) * 10; - - pos[i * 3] = x; - pos[i * 3 + 1] = y; - pos[i * 3 + 2] = z; - - origPos[i * 3] = x; - origPos[i * 3 + 1] = y; - origPos[i * 3 + 2] = z; - - vel.push({ - x: (Math.random() - 0.5) * 0.05, // Slower natural drift - y: (Math.random() - 0.5) * 0.05, - z: (Math.random() - 0.5) * 0.05, - }); - } - return [pos, vel, origPos]; - }, []); - - useFrame((state, delta) => { - // 2. Map Mouse to World Coordinates - // state.pointer is normalized (-1 to 1). Convert to world units using viewport. - const mouseX = (state.pointer.x * viewport.width) / 2; - const mouseY = (state.pointer.y * viewport.height) / 2; - - if (particlesRef.current && linesRef.current) { - const positionsAttr = particlesRef.current.geometry.attributes.position; - const currentPositions = positionsAttr.array as Float32Array; - - // 3. Update Particles - for (let i = 0; i < PARTICLE_COUNT; i++) { - const i3 = i * 3; - - // A. Natural Drift (Gravity) - // We use the "original" position as an anchor to prevent them from flying away too far - // but we add the velocity to keep them moving organically. - originalPositions[i3] += velocities[i].x * delta * 2; - originalPositions[i3 + 1] += velocities[i].y * delta * 2; - - // Bounce logic for the anchor points - if (Math.abs(originalPositions[i3]) > 10) velocities[i].x *= -1; - if (Math.abs(originalPositions[i3 + 1]) > 10) velocities[i].y *= -1; - - // B. Mouse Interaction (The Wave) - // Calculate distance from particle to mouse - const dx = mouseX - originalPositions[i3]; - const dy = mouseY - originalPositions[i3 + 1]; - const dist = Math.sqrt(dx * dx + dy * dy); - - // Apply Wave Effect - // If the mouse is close, we disturb the position - let xOffset = 0; - let yOffset = 0; - let zOffset = 0; - - if (dist < MOUSE_INFLUENCE_RADIUS) { - // 1. Repulsion force (XY Plane) - pushes them slightly aside - const force = (MOUSE_INFLUENCE_RADIUS - dist) / MOUSE_INFLUENCE_RADIUS; - const angle = Math.atan2(dy, dx); - - xOffset = -Math.cos(angle) * force * 2; // Push away X - yOffset = -Math.sin(angle) * force * 2; // Push away Y - - // 2. Wave Ripple (Z Plane) - Sine wave based on distance and time - // This creates the "water ripple" effect in 3D depth - zOffset = Math.sin(dist * 1.5 - state.clock.elapsedTime * 3) * WAVE_AMPLITUDE * force; - } - - // Apply calculated positions - currentPositions[i3] = originalPositions[i3] + xOffset; - currentPositions[i3 + 1] = originalPositions[i3 + 1] + yOffset; - currentPositions[i3 + 2] = originalPositions[i3 + 2] + zOffset; - } - positionsAttr.needsUpdate = true; - - // 4. Update Connections (Plexus) - // Re-calculate lines based on the NEW modified positions - const linePositions: number[] = []; - - for (let i = 0; i < PARTICLE_COUNT; i++) { - for (let j = i + 1; j < PARTICLE_COUNT; j++) { - const x1 = currentPositions[i * 3]; - const y1 = currentPositions[i * 3 + 1]; - const z1 = currentPositions[i * 3 + 2]; - - const x2 = currentPositions[j * 3]; - const y2 = currentPositions[j * 3 + 1]; - const z2 = currentPositions[j * 3 + 2]; - - const dist = Math.sqrt( - Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) + Math.pow(z2 - z1, 2) - ); - - if (dist < CONNECT_DISTANCE) { - linePositions.push(x1, y1, z1, x2, y2, z2); - } - } - } - - linesRef.current.geometry.setAttribute( - "position", - new THREE.Float32BufferAttribute(linePositions, 3) - ); - } - }); - - return ( - - - - - - - - - - - - - - ); -} - -export default function NeuronsGravity() { - return ( -
- - - - -
- ); -} \ No newline at end of file diff --git a/app/components/canvas/RealisticNeeurons.tsx b/app/components/canvas/RealisticNeeurons.tsx deleted file mode 100644 index 30717d8..0000000 --- a/app/components/canvas/RealisticNeeurons.tsx +++ /dev/null @@ -1,259 +0,0 @@ -"use client"; - -import { useMemo, useRef } from "react"; -import { Canvas, useFrame, useThree } from "@react-three/fiber"; -import { MeshDistortMaterial, Sphere, Preload, Float } from "@react-three/drei"; -import { EffectComposer, Bloom, Vignette } from "@react-three/postprocessing"; -import * as THREE from "three"; - -// --- CONFIGURATION --- -const NEURON_COUNT = 15; // Keep low for high-quality geometry -const CONNECTION_DISTANCE = 6.5; -const PULSE_SPEED = 1.8; - -// 1. REALISTIC CELL (Soma + Nucleus) -function NeuronCell({ position }: { position: [number, number, number] }) { - const membraneRef = useRef(null!); - const nucleusRef = useRef(null!); - - // Randomize biology - const size = useMemo(() => 0.5 + Math.random() * 0.3, []); - - useFrame((state) => { - const t = state.clock.getElapsedTime(); - - // Biological breathing/pulsing - if (membraneRef.current) { - const scale = size + Math.sin(t * 2 + position[0]) * 0.05; - membraneRef.current.scale.setScalar(scale); - } - - // Nucleus gentle pulse (faster) - if (nucleusRef.current) { - const nScale = (size * 0.4) + Math.sin(t * 4) * 0.02; - nucleusRef.current.scale.setScalar(nScale); - } - }); - - return ( - - - - {/* A. The Membrane (Outer Shell) */} - - - - - {/* B. The Nucleus (Inner Core) */} - - - - - - - - ); -} - -// 2. SYNAPSE (Axon + Electric Pulse) -function Synapse({ start, end }: { start: THREE.Vector3; end: THREE.Vector3 }) { - const curve = useMemo(() => { - // Create organic curve - const mid = new THREE.Vector3().lerpVectors(start, end, 0.5); - // Randomize control point for "tendon" shape - mid.add(new THREE.Vector3( - (Math.random() - 0.5) * 3, - (Math.random() - 0.5) * 3, - (Math.random() - 0.5) * 3 - )); - return new THREE.QuadraticBezierCurve3(start, mid, end); - }, [start, end]); - - const points = useMemo(() => curve.getPoints(30), [curve]); - const impulseRef = useRef(null!); - - useFrame((state) => { - // Move electric pulse - const t = (state.clock.getElapsedTime() * PULSE_SPEED) % 1; - if (impulseRef.current) { - const pos = curve.getPointAt(t); - impulseRef.current.position.copy(pos); - - // Stretch effect for speed illusion - const tangent = curve.getTangent(t).normalize(); - impulseRef.current.lookAt(pos.clone().add(tangent)); - impulseRef.current.scale.set(0.6, 0.6, 2.5); // Stretch Z - } - }); - - return ( - - {/* The physical connection (Axon) */} - - - [p.x, p.y, p.z]))} - itemSize={3} - /> - - - - - {/* The Traveling Spark (Electricity) */} - - - - - - - ); -} - -// 3. BACKGROUND PARTICLES (Neurotransmitters) -function NeuroDust() { - const count = 200; - const mesh = useRef(null!); - - const particles = useMemo(() => { - const temp = []; - for(let i=0; i new THREE.Object3D(), []); - - useFrame((state) => { - particles.forEach((particle, i) => { - let { t, factor, speed, x, y, z } = particle; - t = particle.t += speed / 2; - const a = Math.cos(t) + Math.sin(t * 1) / 10; - const b = Math.sin(t) + Math.cos(t * 2) / 10; - const s = Math.cos(t); - - dummy.position.set( - x + Math.cos(t) + Math.sin(t) * 2, - y + Math.sin(t) + Math.cos(t) * 2, - z + Math.cos(t) - ); - dummy.scale.setScalar(s * 0.03); // Tiny dust - dummy.rotation.set(s * 5, s * 5, s * 5); - dummy.updateMatrix(); - - if (mesh.current) mesh.current.setMatrixAt(i, dummy.matrix); - }); - if (mesh.current) mesh.current.instanceMatrix.needsUpdate = true; - }); - - return ( - - - - - ); -} - -// 4. MAIN SCENE -function Scene() { - const { viewport } = useThree(); - - // Generate random positions for neurons - const neurons = useMemo(() => { - const temp = []; - for (let i = 0; i < NEURON_COUNT; i++) { - temp.push({ - position: new THREE.Vector3( - (Math.random() - 0.5) * 22, - (Math.random() - 0.5) * 22, - (Math.random() - 0.5) * 10 - ), - id: i - }); - } - return temp; - }, []); - - // Connect them - const connections = useMemo(() => { - const conns = []; - for(let i=0; i { - // Subtle Camera Parallax based on Mouse - const x = (state.pointer.x * viewport.width) / 12; - const y = (state.pointer.y * viewport.height) / 12; - state.camera.position.x = THREE.MathUtils.lerp(state.camera.position.x, x, 0.02); - state.camera.position.y = THREE.MathUtils.lerp(state.camera.position.y, y, 0.02); - state.camera.lookAt(0,0,0); - }); - - return ( - <> - {/* Match gray-950 */} - - - - {neurons.map(n => )} - {connections.map(c => )} - - - {/* POST PROCESSING - The Secret Sauce for Realism */} - - - - - - ); -} - -export default function RealisticNeurons() { - return ( -
- - - - -
- ); -} \ No newline at end of file diff --git a/app/page.tsx b/app/page.tsx index 4025515..3008c56 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -45,7 +45,6 @@ export default function Home() {
- {/* HERO SECTION */}
@@ -106,12 +105,10 @@ export default function Home() {
- {/* CONTENT SECTIONS CONTAINER */}
- {/* === 1. AI VOICE SOAP SECTION === */}
- {/* === 2. DEVICE SHOWCASE SECTION (Modified) === */}
- {/* === 3. AI DIAGNOSIS SECTION === */}
- {/* === 4. APP ECOSYSTEM SECTION === */}