Skip to content
Merged
Show file tree
Hide file tree
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: 29 additions & 14 deletions src/components/Starfield.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import * as THREE from 'three';

const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {
Expand All @@ -10,10 +11,17 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {
const animationFrameRef = useRef(null);

// Component state
const [skyboxLoaded, setSkyboxLoaded] = useState(false);
const [starsVisible, setStarsVisible] = useState(false);
const [starsAnimating, setStarsAnimating] = useState(false);

// Use ref for callback to keep it stable and prevent useEffect re-runs
const onSkyboxLoadedRef = useRef(onSkyboxLoaded);

// Update ref when callback changes, but don't trigger useEffect
useEffect(() => {
onSkyboxLoadedRef.current = onSkyboxLoaded;
}, [onSkyboxLoaded]);

// Animation and scroll tracking references
const scrollProgressRef = useRef(0);
const scrollVelocityRef = useRef(0);
Expand Down Expand Up @@ -75,8 +83,8 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {

// Configuration constants (increased minimum sizes to prevent twinkling)
const STAR_LAYER_CONFIG = {
VERY_DISTANT: { count: 3000, distance: 800, size: 0.6, opacity: 0.4 },
FAR: { count: 2500, distance: 600, size: 0.7, opacity: 0.5 },
// VERY_DISTANT: { count: 3000, distance: 800, size: 0.6, opacity: 0.4 },
// FAR: { count: 2500, distance: 600, size: 0.7, opacity: 0.5 },
DISTANT: { count: 2000, distance: 450, size: 0.8, opacity: 0.6 },
MEDIUM_FAR: { count: 1500, distance: 350, size: 0.9, opacity: 0.7 },
MEDIUM: { count: 1000, distance: 250, size: 1.0, opacity: 0.8 }
Expand Down Expand Up @@ -212,11 +220,16 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {

// Create and add skybox mesh
skyboxMesh = new THREE.Mesh(sphereGeometry, skyboxMaterial);

// Initial skybox positioning
skyboxMesh.rotation.x = Math.PI * -0.1;
skyboxMesh.rotation.y = Math.PI * 0;
skyboxMesh.rotation.z = Math.PI * 0;

scene.add(skyboxMesh);

// Initialize stars and notify completion
setSkyboxLoaded(true);
onSkyboxLoaded();
onSkyboxLoadedRef.current();
setStarsVisible(true);

// Start the animation loop
Expand All @@ -226,8 +239,7 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {
(error) => {
console.error('Failed to load galaxy texture:', error);
// No fallback - just proceed with black background and stars
setSkyboxLoaded(true);
onSkyboxLoaded();
onSkyboxLoadedRef.current();
setStarsVisible(true);
animate();
}
Expand All @@ -236,8 +248,8 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {
// Create star layers with fade-in effect
const starLayers = [];
const layerConfigs = [
STAR_LAYER_CONFIG.VERY_DISTANT,
STAR_LAYER_CONFIG.FAR,
// STAR_LAYER_CONFIG.VERY_DISTANT,
// STAR_LAYER_CONFIG.FAR,
STAR_LAYER_CONFIG.DISTANT,
STAR_LAYER_CONFIG.MEDIUM_FAR,
STAR_LAYER_CONFIG.MEDIUM
Expand Down Expand Up @@ -366,17 +378,14 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {
skyboxMesh.material.opacity += ANIMATION_CONFIG.skyboxFadeSpeed;
}

// Calculate scroll-based motion
const scrollProgress = scrollProgressRef.current;

// Decay scroll velocity when not actively scrolling
scrollVelocityRef.current *= ANIMATION_CONFIG.velocityDecay;

// Convert scroll velocity to speed multiplier (restore original values)
const velocityFactor = Math.min(scrollVelocityRef.current / ANIMATION_CONFIG.maxVelocity, 1.0);
const scrollAmplification = 2.5 + velocityFactor * 40;

starLayersRef.current.forEach((starLayer, index) => {
starLayersRef.current.forEach((starLayer) => {
if (starLayer && starLayer.userData) {
const distance = starLayer.userData.distance;

Expand Down Expand Up @@ -446,7 +455,7 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {

// Return cleanup function
return cleanup;
}, []);
}, []); // Empty dependency array - only run once

return (
<div
Expand All @@ -464,4 +473,10 @@ const Starfield = ({ onSkyboxLoaded = () => { }, uiVisible = false }) => {
);
};

// PropTypes validation
Starfield.propTypes = {
onSkyboxLoaded: PropTypes.func,
uiVisible: PropTypes.bool
};

export default Starfield;
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

--border_radius: 20px;
--internal_padding: 20px;
--item_background_color: rgba(0, 0, 0, 0.75);
--item_background_color: rgba(0, 0, 0, 0.5);
--button_size: 25px;
--transition_time: 0.4s;
}
Expand Down