Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions frontend/src/components/login/NetworkGlobe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ interface CentralNodeChild extends THREE.Object3D {
const NetworkGlobe = ({ isLoaded = true }: NetworkGlobeProps) => {
const { t } = useTranslation();
const globeRef = useRef<THREE.Mesh>(null);
const gridLinesRef = useRef<THREE.Group>(null);
const centralNodeRef = useRef<THREE.Group>(null);
const dataFlowsRef = useRef<THREE.Group>(null);
const rotatingContentRef = useRef<THREE.Group>(null);
const frameCount = useRef(0);

// Track document visibility to pause rendering when tab/page is not active
Expand Down Expand Up @@ -231,16 +233,17 @@ const NetworkGlobe = ({ isLoaded = true }: NetworkGlobeProps) => {

// Increment frame counter
frameCount.current += 1;
const time = state.clock.getElapsedTime();

// Update animation progress for reveal effect - only when loading
if (isLoaded && animationProgress < 1) {
setAnimationProgress(Math.min(animationProgress + 0.01, 1));
}

// Rotate the globe slowly - limit updates for better performance
if (globeRef.current && frameCount.current % 2 === 0) {
globeRef.current.rotation.y = state.clock.getElapsedTime() * 0.05;
globeRef.current.rotation.x = Math.sin(state.clock.getElapsedTime() * 0.2) * 0.02;
globeRef.current.rotation.y = time * 0.05;
globeRef.current.rotation.x = Math.sin(time * 0.15) * 0.04;
globeRef.current.rotation.z = Math.cos(time * 0.08) * 0.015;

// Update material opacity
if (globeMaterial.opacity !== 0.08 * animationProgress) {
Expand All @@ -252,12 +255,18 @@ const NetworkGlobe = ({ isLoaded = true }: NetworkGlobeProps) => {
globeRef.current.scale.setScalar(scale);
}

// Rotate grid lines to match globe rotation with same slow speed
if (gridLinesRef.current && frameCount.current % 2 === 0) {
gridLinesRef.current.rotation.y = time * 0.05;
gridLinesRef.current.rotation.x = Math.sin(time * 0.15) * 0.04;
gridLinesRef.current.rotation.z = Math.cos(time * 0.08) * 0.015;
}

// Animate central node - less frequently
if (centralNodeRef.current && frameCount.current % 3 === 0) {
centralNodeRef.current.rotation.y = state.clock.getElapsedTime() * 0.2;
centralNodeRef.current.scale.setScalar(
(1 + Math.sin(state.clock.getElapsedTime() * 1.5) * 0.05) * animationProgress
);
centralNodeRef.current.rotation.y = time * 0.15;
centralNodeRef.current.rotation.x = Math.sin(time * 0.2) * 0.05;
centralNodeRef.current.scale.setScalar((1 + Math.sin(time * 1.5) * 0.05) * animationProgress);

// Fade in the central node with throttled updates
centralNodeRef.current.children.forEach((child: CentralNodeChild) => {
Expand All @@ -271,6 +280,13 @@ const NetworkGlobe = ({ isLoaded = true }: NetworkGlobeProps) => {
});
}

// Rotate the cluster group around the central node - same frequency as central node
if (rotatingContentRef.current && frameCount.current % 3 === 0) {
rotatingContentRef.current.rotation.y = time * 0.05; // Match globe speed
rotatingContentRef.current.rotation.x = Math.sin(time * 0.15) * 0.04;
rotatingContentRef.current.rotation.z = Math.cos(time * 0.08) * 0.015;
}

// Animate data flows - only every 3 frames
if (dataFlowsRef.current && frameCount.current % 3 === 0) {
dataFlowsRef.current.children.forEach((flow: FlowChild, i) => {
Expand Down Expand Up @@ -299,7 +315,7 @@ const NetworkGlobe = ({ isLoaded = true }: NetworkGlobeProps) => {
</Sphere>

{/* Grid lines for the globe - optimized with shared geometry */}
<group rotation={[0, 0, 0]}>
<group ref={gridLinesRef} rotation={[0, 0, 0]}>
{Array.from({ length: 4 }).map((_, idx) => (
<Torus
key={`h-${idx}`}
Expand Down Expand Up @@ -335,10 +351,13 @@ const NetworkGlobe = ({ isLoaded = true }: NetworkGlobeProps) => {
<LogoElement animate={isLoaded && isDocumentVisible} />
</group>

{/* Clusters of nodes */}
{clusters.map((cluster, idx) => (
<Cluster key={idx} {...cluster} isActive={isDocumentVisible} />
))}
{/* Rotating cluster group */}
<group ref={rotatingContentRef}>
{/* Clusters of nodes */}
{clusters.map((cluster, idx) => (
<Cluster key={idx} {...cluster} isActive={isDocumentVisible} />
))}
</group>

{/* Data flow connections - use reduced detail and memoized materials */}
<group ref={dataFlowsRef}>
Expand Down
Loading