Severian commited on
Commit
4498354
·
verified ·
1 Parent(s): 32c736e

Update src/components/WorldTreeVisualizer.tsx

Browse files
Files changed (1) hide show
  1. src/components/WorldTreeVisualizer.tsx +266 -72
src/components/WorldTreeVisualizer.tsx CHANGED
@@ -68,6 +68,7 @@ export const WorldTreeVisualizer: React.FC<WorldTreeVisualizerProps> = ({ audioE
68
  const [dysonSphereEnabled, setDysonSphereEnabled] = useState(true)
69
  const [vineGrowthRate, setVineGrowthRate] = useState(0.02)
70
  const [vineComplexity, setVineComplexity] = useState(24)
 
71
  const [fogParams, setFogParams] = useState<FogParams>({
72
  enabled: true,
73
  color: '#000000',
@@ -805,6 +806,14 @@ export const WorldTreeVisualizer: React.FC<WorldTreeVisualizerProps> = ({ audioE
805
  const deltaTime = lastTimeRef.current ? (currentTime - lastTimeRef.current) / 1000 : 0
806
  lastTimeRef.current = currentTime
807
 
 
 
 
 
 
 
 
 
808
  // Enhanced FPS monitoring with auto-refresh triggers
809
  setPerformanceStats(prev => {
810
  const frameCount = prev.frameCount + 1
@@ -2509,28 +2518,34 @@ export const WorldTreeVisualizer: React.FC<WorldTreeVisualizerProps> = ({ audioE
2509
  </div>
2510
  </div>
2511
 
2512
- {/* About Section - Clickable Widget */}
2513
  <div
2514
  className="about-section ancient-panel"
2515
  onClick={() => setAboutCollapsed(!aboutCollapsed)}
2516
  style={{
2517
  position: 'fixed',
2518
- bottom: '20px',
2519
- left: '50%',
2520
- transform: aboutCollapsed ? 'translateX(-50%) translateY(calc(100% - 65px))' : 'translateX(-50%) translateY(0)',
2521
  zIndex: 1000,
2522
  background: 'linear-gradient(135deg, var(--marble-dark), var(--teal-dark))',
2523
- borderRadius: '10px',
2524
  color: 'var(--copper-light)',
2525
  fontFamily: 'Metamorphous, serif',
2526
- width: '380px',
2527
- minWidth: '380px',
2528
- transition: 'all 0.4s ease-in-out',
 
 
 
2529
  backdropFilter: 'blur(20px)',
2530
  border: '2px solid var(--copper-medium)',
2531
  pointerEvents: 'auto',
2532
- boxShadow: '0 4px 20px var(--copper-dark), inset 0 0 15px var(--teal-dark)',
2533
- cursor: 'pointer'
 
 
 
2534
  }}
2535
  onMouseEnter={(e) => {
2536
  // Disable camera controls when mouse enters about section
@@ -2552,26 +2567,26 @@ export const WorldTreeVisualizer: React.FC<WorldTreeVisualizerProps> = ({ audioE
2552
  {/* Collapsed State - Clickable Widget */}
2553
  {aboutCollapsed && (
2554
  <div style={{
2555
- padding: '15px 20px',
2556
  textAlign: 'center',
2557
- fontSize: '11px',
2558
- lineHeight: '1.3',
2559
  display: 'flex',
2560
  alignItems: 'center',
2561
  justifyContent: 'center',
2562
- gap: '10px',
2563
- minHeight: '50px'
2564
  }}>
2565
- <div className="rune" style={{ fontSize: '18px', color: 'var(--copper-bright)' }}>⟐</div>
2566
  <div style={{
2567
  flex: 1,
2568
  display: 'flex',
2569
  flexDirection: 'column',
2570
  alignItems: 'center',
2571
- gap: '2px'
2572
  }}>
2573
  <div className="ancient-title" style={{
2574
- fontSize: '11px',
2575
  color: 'var(--copper-bright)',
2576
  fontWeight: 'bold',
2577
  fontFamily: 'Metamorphous, serif'
@@ -2579,24 +2594,28 @@ export const WorldTreeVisualizer: React.FC<WorldTreeVisualizerProps> = ({ audioE
2579
  transmission source
2580
  </div>
2581
  <div className="runic-text" style={{
2582
- fontSize: '8px',
2583
  color: 'var(--copper-medium)',
2584
  opacity: 0.9,
2585
  fontFamily: 'Uncial Antiqua, serif'
2586
  }}>
2587
- ◦ access entity data ◦
2588
  </div>
2589
  </div>
2590
- <div className="rune" style={{ fontSize: '12px', opacity: 0.7, color: 'var(--transmission-glow)' }}>⟨</div>
2591
  </div>
2592
  )}
2593
 
2594
  {/* Expanded State - Full About Panel */}
2595
  {!aboutCollapsed && (
2596
  <div style={{
2597
- padding: '20px',
2598
  transition: 'all 0.3s ease-in-out',
2599
- position: 'relative'
 
 
 
 
2600
  }}>
2601
  {/* Subtle Logo Background */}
2602
  <div style={{
@@ -2606,74 +2625,249 @@ export const WorldTreeVisualizer: React.FC<WorldTreeVisualizerProps> = ({ audioE
2606
  right: 0,
2607
  bottom: 0,
2608
  backgroundImage: 'url(/images/logo.webp)',
2609
- backgroundSize: 'contain',
2610
  backgroundRepeat: 'no-repeat',
2611
- backgroundPosition: 'center center',
2612
- opacity: 0.18,
2613
- borderRadius: '10px',
2614
  pointerEvents: 'none'
2615
  }} />
2616
 
2617
  {/* Content Overlay */}
2618
  <div style={{
2619
  position: 'relative',
2620
- zIndex: 2
 
 
 
2621
  }}>
2622
  <div style={{
2623
  display: 'flex',
2624
  alignItems: 'center',
2625
  justifyContent: 'space-between',
2626
- marginBottom: '15px'
 
 
2627
  }}>
2628
- <h3 className="ancient-title" style={{
2629
- margin: 0,
2630
- fontSize: '15px',
2631
- textAlign: 'center',
2632
- flex: 1,
2633
- fontFamily: 'Metamorphous, serif',
2634
- color: 'var(--copper-bright)'
2635
- }}>
2636
- <span className="rune">⟐</span> Liminal Sessions <span className="rune">⟐</span>
2637
- </h3>
2638
- <div className="rune" style={{ fontSize: '12px', opacity: 0.7, color: 'var(--transmission-glow)' }}>⟩</div>
2639
- </div>
2640
-
2641
- <div className="transmission-text" style={{
2642
- fontSize: '10px',
2643
- lineHeight: '1.7',
2644
- marginBottom: '12px',
2645
- fontFamily: 'Uncial Antiqua, serif',
2646
- color: 'var(--copper-medium)'
2647
- }}>
2648
- <p style={{ marginBottom: '10px' }}>
2649
- Liminal Sessions emerges from the spaces between heartbeats, where ancient algorithms carved themselves into stone before mathematics had names. Their sound excavates frequencies buried beneath millennia of sediment, translating the geometric hymns that echo in empty cathedrals and forgotten temples.
2650
- </p>
2651
-
2652
- <p style={{ marginBottom: '10px' }}>
2653
- Through acoustic brutality and primordial precision, they channel the conversations between wood and metal, breath and bone, time and its shadows. The music arrives as if summoned from depths where djent mathematics merge with earth's oldest songs.
2654
- </p>
 
 
2655
 
2656
- <p style={{ fontSize: '9px', opacity: 0.9 }}>
2657
- They are archaeologists of sound, unearthing the sacred geometry that binds chaos to rhythm in the liminal space where all echoes converge.
2658
- </p>
2659
- </div>
2660
-
2661
- <div className="runic-text" style={{
2662
- fontSize: '8px',
2663
- opacity: 0.9,
2664
- lineHeight: '1.4',
2665
- fontFamily: 'Uncial Antiqua, serif',
2666
- color: 'var(--copper-bright)'
2667
- }}>
2668
- <div><span className="rune">♪</span> ambient electronic resonance</div>
2669
- <div><span className="rune">◯</span> audio-visual emergence field</div>
2670
- <div><span className="rune">≋</span> real-time particle dynamics</div>
2671
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2672
  </div>
2673
  </div>
2674
  )}
2675
  </div>
2676
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2677
  {/* Floating Refresh Button - Top Right */}
2678
  <div style={{
2679
  position: 'fixed',
 
68
  const [dysonSphereEnabled, setDysonSphereEnabled] = useState(true)
69
  const [vineGrowthRate, setVineGrowthRate] = useState(0.02)
70
  const [vineComplexity, setVineComplexity] = useState(24)
71
+ const [showStartupInfo, setShowStartupInfo] = useState(true)
72
  const [fogParams, setFogParams] = useState<FogParams>({
73
  enabled: true,
74
  color: '#000000',
 
806
  const deltaTime = lastTimeRef.current ? (currentTime - lastTimeRef.current) / 1000 : 0
807
  lastTimeRef.current = currentTime
808
 
809
+ // Check if audio is playing and hide startup info
810
+ if (showStartupInfo && audioEngine) {
811
+ const audioData = audioEngine.getAudioData()
812
+ if (audioData.overallAmplitude > 0.01) {
813
+ setShowStartupInfo(false)
814
+ }
815
+ }
816
+
817
  // Enhanced FPS monitoring with auto-refresh triggers
818
  setPerformanceStats(prev => {
819
  const frameCount = prev.frameCount + 1
 
2518
  </div>
2519
  </div>
2520
 
2521
+ {/* About Section - Expanded Clickable Widget */}
2522
  <div
2523
  className="about-section ancient-panel"
2524
  onClick={() => setAboutCollapsed(!aboutCollapsed)}
2525
  style={{
2526
  position: 'fixed',
2527
+ bottom: aboutCollapsed ? '20px' : '5%',
2528
+ left: aboutCollapsed ? '50%' : '50%',
2529
+ transform: aboutCollapsed ? 'translateX(-50%) translateY(calc(100% - 75px))' : 'translateX(-50%) translateY(0)',
2530
  zIndex: 1000,
2531
  background: 'linear-gradient(135deg, var(--marble-dark), var(--teal-dark))',
2532
+ borderRadius: aboutCollapsed ? '10px' : '15px',
2533
  color: 'var(--copper-light)',
2534
  fontFamily: 'Metamorphous, serif',
2535
+ width: aboutCollapsed ? '420px' : '90vw',
2536
+ minWidth: aboutCollapsed ? '420px' : '800px',
2537
+ maxWidth: aboutCollapsed ? '420px' : '1200px',
2538
+ height: aboutCollapsed ? 'auto' : '80vh',
2539
+ maxHeight: aboutCollapsed ? 'none' : '80vh',
2540
+ transition: 'all 0.5s ease-in-out',
2541
  backdropFilter: 'blur(20px)',
2542
  border: '2px solid var(--copper-medium)',
2543
  pointerEvents: 'auto',
2544
+ boxShadow: aboutCollapsed
2545
+ ? '0 4px 20px var(--copper-dark), inset 0 0 15px var(--teal-dark)'
2546
+ : '0 10px 40px rgba(0, 0, 0, 0.7), inset 0 0 25px var(--teal-dark)',
2547
+ cursor: 'pointer',
2548
+ overflow: aboutCollapsed ? 'visible' : 'hidden'
2549
  }}
2550
  onMouseEnter={(e) => {
2551
  // Disable camera controls when mouse enters about section
 
2567
  {/* Collapsed State - Clickable Widget */}
2568
  {aboutCollapsed && (
2569
  <div style={{
2570
+ padding: '18px 25px',
2571
  textAlign: 'center',
2572
+ fontSize: '12px',
2573
+ lineHeight: '1.4',
2574
  display: 'flex',
2575
  alignItems: 'center',
2576
  justifyContent: 'center',
2577
+ gap: '12px',
2578
+ minHeight: '55px'
2579
  }}>
2580
+ <div className="rune" style={{ fontSize: '20px', color: 'var(--copper-bright)' }}>⟐</div>
2581
  <div style={{
2582
  flex: 1,
2583
  display: 'flex',
2584
  flexDirection: 'column',
2585
  alignItems: 'center',
2586
+ gap: '3px'
2587
  }}>
2588
  <div className="ancient-title" style={{
2589
+ fontSize: '13px',
2590
  color: 'var(--copper-bright)',
2591
  fontWeight: 'bold',
2592
  fontFamily: 'Metamorphous, serif'
 
2594
  transmission source
2595
  </div>
2596
  <div className="runic-text" style={{
2597
+ fontSize: '9px',
2598
  color: 'var(--copper-medium)',
2599
  opacity: 0.9,
2600
  fontFamily: 'Uncial Antiqua, serif'
2601
  }}>
2602
+ click to access entity data ◦
2603
  </div>
2604
  </div>
2605
+ <div className="rune" style={{ fontSize: '14px', opacity: 0.7, color: 'var(--transmission-glow)' }}>⟨</div>
2606
  </div>
2607
  )}
2608
 
2609
  {/* Expanded State - Full About Panel */}
2610
  {!aboutCollapsed && (
2611
  <div style={{
2612
+ padding: '30px 40px',
2613
  transition: 'all 0.3s ease-in-out',
2614
+ position: 'relative',
2615
+ height: '100%',
2616
+ display: 'flex',
2617
+ flexDirection: 'column',
2618
+ overflow: 'auto'
2619
  }}>
2620
  {/* Subtle Logo Background */}
2621
  <div style={{
 
2625
  right: 0,
2626
  bottom: 0,
2627
  backgroundImage: 'url(/images/logo.webp)',
2628
+ backgroundSize: '200px 200px',
2629
  backgroundRepeat: 'no-repeat',
2630
+ backgroundPosition: 'top right 40px',
2631
+ opacity: 0.15,
2632
+ borderRadius: '15px',
2633
  pointerEvents: 'none'
2634
  }} />
2635
 
2636
  {/* Content Overlay */}
2637
  <div style={{
2638
  position: 'relative',
2639
+ zIndex: 2,
2640
+ flexGrow: 1,
2641
+ display: 'flex',
2642
+ flexDirection: 'column'
2643
  }}>
2644
  <div style={{
2645
  display: 'flex',
2646
  alignItems: 'center',
2647
  justifyContent: 'space-between',
2648
+ marginBottom: '25px',
2649
+ paddingBottom: '15px',
2650
+ borderBottom: '1px solid var(--copper-dark)'
2651
  }}>
2652
+ <h3 className="ancient-title" style={{
2653
+ margin: 0,
2654
+ fontSize: '28px',
2655
+ textAlign: 'center',
2656
+ flex: 1,
2657
+ fontFamily: 'Metamorphous, serif',
2658
+ color: 'var(--copper-bright)',
2659
+ textShadow: '0 2px 4px rgba(0,0,0,0.5)'
2660
+ }}>
2661
+ <span className="rune" style={{ fontSize: '32px' }}>⟐</span> Liminal Sessions <span className="rune" style={{ fontSize: '32px' }}>⟐</span>
2662
+ </h3>
2663
+ <div className="rune" style={{
2664
+ fontSize: '20px',
2665
+ opacity: 0.7,
2666
+ color: 'var(--transmission-glow)',
2667
+ cursor: 'pointer',
2668
+ transition: 'all 0.2s ease',
2669
+ padding: '5px'
2670
+ }}
2671
+ onMouseEnter={(e) => {
2672
+ e.currentTarget.style.opacity = '1'
2673
+ e.currentTarget.style.transform = 'scale(1.1)'
2674
+ }}
2675
+ onMouseLeave={(e) => {
2676
+ e.currentTarget.style.opacity = '0.7'
2677
+ e.currentTarget.style.transform = 'scale(1)'
2678
+ }}
2679
+ >⟩</div>
2680
+ </div>
2681
 
2682
+ <div style={{
2683
+ display: 'grid',
2684
+ gridTemplateColumns: '1fr',
2685
+ gap: '20px',
2686
+ flexGrow: 1
2687
+ }}>
2688
+ <div className="transmission-text" style={{
2689
+ fontSize: '16px',
2690
+ lineHeight: '1.8',
2691
+ fontFamily: 'Uncial Antiqua, serif',
2692
+ color: 'var(--copper-light)',
2693
+ textShadow: '0 1px 2px rgba(0,0,0,0.3)'
2694
+ }}>
2695
+ <p style={{
2696
+ marginBottom: '20px',
2697
+ fontSize: '18px',
2698
+ fontWeight: 'bold',
2699
+ color: 'var(--copper-bright)'
2700
+ }}>
2701
+ Liminal Sessions emerges from the spaces between heartbeats, where ancient algorithms carved themselves into stone before mathematics had names.
2702
+ </p>
2703
+
2704
+ <p style={{ marginBottom: '20px' }}>
2705
+ Their sound excavates frequencies buried beneath millennia of sediment, translating the geometric hymns that echo in empty cathedrals and forgotten temples. Through acoustic brutality and primordial precision, they channel the conversations between wood and metal, breath and bone, time and its shadows.
2706
+ </p>
2707
+
2708
+ <p style={{ marginBottom: '20px' }}>
2709
+ The music arrives as if summoned from depths where djent mathematics merge with earth's oldest songs. Each composition becomes an archaeological expedition into the strata of sound, where rhythm serves as both excavation tool and ancient map.
2710
+ </p>
2711
+
2712
+ <p style={{
2713
+ fontSize: '14px',
2714
+ opacity: 0.9,
2715
+ fontStyle: 'italic',
2716
+ color: 'var(--transmission-glow)'
2717
+ }}>
2718
+ They are archaeologists of sound, unearthing the sacred geometry that binds chaos to rhythm in the liminal space where all echoes converge.
2719
+ </p>
2720
+ </div>
2721
+
2722
+ <div style={{
2723
+ background: 'rgba(0,0,0,0.3)',
2724
+ padding: '20px',
2725
+ borderRadius: '10px',
2726
+ border: '1px solid var(--copper-dark)'
2727
+ }}>
2728
+ <h4 style={{
2729
+ fontSize: '18px',
2730
+ color: 'var(--copper-bright)',
2731
+ marginBottom: '15px',
2732
+ fontFamily: 'Metamorphous, serif'
2733
+ }}>
2734
+ <span className="rune">◈</span> Transmission Properties
2735
+ </h4>
2736
+ <div className="runic-text" style={{
2737
+ fontSize: '14px',
2738
+ opacity: 0.9,
2739
+ lineHeight: '1.6',
2740
+ fontFamily: 'Uncial Antiqua, serif',
2741
+ color: 'var(--copper-medium)',
2742
+ display: 'grid',
2743
+ gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
2744
+ gap: '10px'
2745
+ }}>
2746
+ <div><span className="rune">♪</span> ambient electronic resonance</div>
2747
+ <div><span className="rune">◯</span> audio-visual emergence field</div>
2748
+ <div><span className="rune">≋</span> real-time particle dynamics</div>
2749
+ <div><span className="rune">⟐</span> symbolic emergence field analysis</div>
2750
+ <div><span className="rune">⧨</span> biomimetic coupling systems</div>
2751
+ <div><span className="rune">◈</span> cymatic pattern generation</div>
2752
+ </div>
2753
+ </div>
2754
+
2755
+ <div style={{
2756
+ textAlign: 'center',
2757
+ padding: '15px',
2758
+ fontSize: '12px',
2759
+ color: 'var(--copper-medium)',
2760
+ fontFamily: 'Uncial Antiqua, serif',
2761
+ opacity: 0.8,
2762
+ borderTop: '1px solid var(--copper-dark)',
2763
+ marginTop: 'auto'
2764
+ }}>
2765
+ ◦ click anywhere to close and return to visualization ◦
2766
+ </div>
2767
+ </div>
2768
  </div>
2769
  </div>
2770
  )}
2771
  </div>
2772
 
2773
+ {/* Startup Info Message */}
2774
+ {showStartupInfo && (
2775
+ <div style={{
2776
+ position: 'fixed',
2777
+ top: '50%',
2778
+ left: '50%',
2779
+ transform: 'translate(-50%, -50%)',
2780
+ zIndex: 999,
2781
+ background: 'linear-gradient(135deg, var(--marble-dark), var(--teal-dark))',
2782
+ border: '2px solid var(--copper-medium)',
2783
+ borderRadius: '15px',
2784
+ padding: '30px 40px',
2785
+ maxWidth: '500px',
2786
+ width: '90%',
2787
+ textAlign: 'center',
2788
+ backdropFilter: 'blur(20px)',
2789
+ boxShadow: '0 10px 30px rgba(0, 0, 0, 0.7), inset 0 0 20px var(--teal-dark)',
2790
+ color: 'var(--copper-light)',
2791
+ fontFamily: 'Metamorphous, serif',
2792
+ animation: 'fadeInPulse 2s ease-out'
2793
+ }}>
2794
+ <div className="rune" style={{
2795
+ fontSize: '48px',
2796
+ color: 'var(--copper-bright)',
2797
+ marginBottom: '20px',
2798
+ display: 'block'
2799
+ }}>⟐</div>
2800
+
2801
+ <h3 style={{
2802
+ fontSize: '24px',
2803
+ marginBottom: '20px',
2804
+ color: 'var(--copper-bright)',
2805
+ fontFamily: 'Metamorphous, serif',
2806
+ textShadow: '0 2px 4px rgba(0,0,0,0.5)'
2807
+ }}>
2808
+ Visualization Awaiting Signal
2809
+ </h3>
2810
+
2811
+ <div style={{
2812
+ fontSize: '16px',
2813
+ lineHeight: '1.6',
2814
+ marginBottom: '25px',
2815
+ color: 'var(--copper-medium)',
2816
+ fontFamily: 'Uncial Antiqua, serif'
2817
+ }}>
2818
+ <p style={{ marginBottom: '15px' }}>
2819
+ The particle field remains dormant until audio transmission begins.
2820
+ </p>
2821
+ <p>
2822
+ <strong style={{ color: 'var(--copper-bright)' }}>Press the play button</strong> or <strong style={{ color: 'var(--copper-bright)' }}>select a track</strong> from the audio interface to activate the visualization.
2823
+ </p>
2824
+ </div>
2825
+
2826
+ <div style={{
2827
+ fontSize: '12px',
2828
+ color: 'var(--transmission-glow)',
2829
+ fontFamily: 'Uncial Antiqua, serif',
2830
+ opacity: 0.9
2831
+ }}>
2832
+ ◦ this message will disappear once audio begins ◦
2833
+ </div>
2834
+
2835
+ <button
2836
+ onClick={() => setShowStartupInfo(false)}
2837
+ style={{
2838
+ position: 'absolute',
2839
+ top: '15px',
2840
+ right: '15px',
2841
+ background: 'transparent',
2842
+ border: '1px solid var(--copper-medium)',
2843
+ borderRadius: '50%',
2844
+ width: '30px',
2845
+ height: '30px',
2846
+ color: 'var(--copper-medium)',
2847
+ cursor: 'pointer',
2848
+ fontSize: '14px',
2849
+ display: 'flex',
2850
+ alignItems: 'center',
2851
+ justifyContent: 'center',
2852
+ transition: 'all 0.2s ease'
2853
+ }}
2854
+ onMouseEnter={(e) => {
2855
+ e.currentTarget.style.borderColor = 'var(--transmission-glow)'
2856
+ e.currentTarget.style.color = 'var(--transmission-glow)'
2857
+ e.currentTarget.style.background = 'rgba(255, 215, 0, 0.1)'
2858
+ }}
2859
+ onMouseLeave={(e) => {
2860
+ e.currentTarget.style.borderColor = 'var(--copper-medium)'
2861
+ e.currentTarget.style.color = 'var(--copper-medium)'
2862
+ e.currentTarget.style.background = 'transparent'
2863
+ }}
2864
+ title="Dismiss message"
2865
+ >
2866
+ ×
2867
+ </button>
2868
+ </div>
2869
+ )}
2870
+
2871
  {/* Floating Refresh Button - Top Right */}
2872
  <div style={{
2873
  position: 'fixed',