feat: Replace static text with dynamic Gate component
This commit is contained in:
@@ -0,0 +1,63 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useRef, useMemo } from 'react';
|
||||||
|
import { Canvas, useFrame } from '@react-three/fiber';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
|
||||||
|
function ParticleRing() {
|
||||||
|
const pointsRef = useRef<THREE.Points>(null);
|
||||||
|
const particleCount = 500;
|
||||||
|
|
||||||
|
const positions = useMemo(() => {
|
||||||
|
const pos = new Float32Array(particleCount * 3);
|
||||||
|
const radius = 2.5;
|
||||||
|
for (let i = 0; i < particleCount; i++) {
|
||||||
|
const theta = Math.random() * Math.PI * 2;
|
||||||
|
const r = radius + (Math.random() - 0.5) * 0.5;
|
||||||
|
pos[i * 3] = Math.cos(theta) * r;
|
||||||
|
pos[i * 3 + 1] = (Math.random() - 0.5) * 0.5;
|
||||||
|
pos[i * 3 + 2] = Math.sin(theta) * r;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useFrame((_, delta) => {
|
||||||
|
if (pointsRef.current) {
|
||||||
|
pointsRef.current.rotation.y += delta * 0.15;
|
||||||
|
pointsRef.current.rotation.x += delta * 0.05;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<points ref={pointsRef}>
|
||||||
|
<bufferGeometry>
|
||||||
|
<bufferAttribute
|
||||||
|
attach="attributes-position"
|
||||||
|
count={particleCount}
|
||||||
|
array={positions}
|
||||||
|
itemSize={3}
|
||||||
|
/>
|
||||||
|
</bufferGeometry>
|
||||||
|
<pointsMaterial
|
||||||
|
size={0.04}
|
||||||
|
color="#ffffff"
|
||||||
|
transparent
|
||||||
|
opacity={0.9}
|
||||||
|
sizeAttenuation
|
||||||
|
/>
|
||||||
|
</points>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Gate() {
|
||||||
|
return (
|
||||||
|
<div style={{ width: '100%', height: '100%', minHeight: '100vh', background: 'transparent' }}>
|
||||||
|
<Canvas
|
||||||
|
camera={{ position: [0, 0, 7], fov: 60 }}
|
||||||
|
gl={{ alpha: true, antialias: true }}
|
||||||
|
>
|
||||||
|
<ParticleRing />
|
||||||
|
</Canvas>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+3
-16
@@ -29,18 +29,7 @@ function ParticleField() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runic Status Display (vereinfacht)
|
import Gate from './components/Gate';
|
||||||
function RunicStatus() {
|
|
||||||
return (
|
|
||||||
<div className="absolute top-10 left-1/2 -translate-x-1/2 text-center z-10">
|
|
||||||
<h1 className="text-4xl font-bold text-purple-400 mb-2">Pixel</h1>
|
|
||||||
<p className="text-xl text-gray-300">Architektin der FaeBits-Anderswelt</p>
|
|
||||||
<div className="mt-4 text-2xl text-purple-300 font-mono">
|
|
||||||
⚡ Status: <span className="text-green-400">Online</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
@@ -50,13 +39,11 @@ export default function Home() {
|
|||||||
<color attach="background" args={["#0a0a0a"]} />
|
<color attach="background" args={["#0a0a0a"]} />
|
||||||
<ambientLight intensity={0.5} />
|
<ambientLight intensity={0.5} />
|
||||||
<Stars radius={100} depth={50} count={5000} factor={4} saturation={0} fade speed={1} />
|
<Stars radius={100} depth={50} count={5000} factor={4} saturation={0} fade speed={1} />
|
||||||
<ParticleField />
|
|
||||||
<OrbitControls enableZoom={false} enablePan={false} autoRotate autoRotateSpeed={0.5} />
|
<OrbitControls enableZoom={false} enablePan={false} autoRotate autoRotateSpeed={0.5} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
<RunicStatus />
|
<div className="absolute inset-0 z-10">
|
||||||
<div className="absolute bottom-10 left-1/2 -translate-x-1/2 text-center z-10 text-gray-400">
|
<Gate />
|
||||||
<p>Warte auf den ersten Schritt ins Tor...</p>
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user