@principal-ai/file-city-react 0.5.24 → 0.5.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"FileCity3D.d.ts","sourceRoot":"","sources":["../../../src/components/FileCity3D/FileCity3D.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FileCity3D.d.ts","sourceRoot":"","sources":["../../../src/components/FileCity3D/FileCity3D.tsx"],"names":[],"mappings":"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"}
@@ -472,59 +472,37 @@ function InstancedBuildings({ buildings, centerOffset, onHover, onClick, hovered
472
472
  buildingIndex: d.index,
473
473
  })), growProgress: growProgress, minHeight: minHeight, baseOffset: baseOffset, springDuration: springDuration, heightMultipliersRef: heightMultipliersRef })] }));
474
474
  }
475
- function AnimatedIcon({ x, z, targetHeight, iconSize, texture, opacity, growProgress, staggerDelayMs, springDuration, }) {
475
+ function AnimatedIcon({ x, z, targetHeight, iconSize, texture, opacity, growProgress, }) {
476
476
  const meshRef = useRef(null);
477
- const startTimeRef = useRef(null);
478
477
  const materialRef = useRef(null);
479
- useFrame(({ clock }) => {
478
+ useFrame(() => {
480
479
  if (!meshRef.current)
481
480
  return;
482
- if (startTimeRef.current === null && growProgress > 0) {
483
- startTimeRef.current = clock.elapsedTime * 1000;
484
- }
485
- const currentTime = clock.elapsedTime * 1000;
486
- const animStartTime = startTimeRef.current ?? currentTime;
487
- // Calculate per-icon animation progress
488
- const elapsed = currentTime - animStartTime - staggerDelayMs;
489
- let animProgress = growProgress;
490
- if (growProgress > 0 && elapsed >= 0) {
491
- const t = Math.min(elapsed / springDuration, 1);
492
- const eased = 1 - Math.pow(1 - t, 3);
493
- animProgress = eased * growProgress;
494
- }
495
- else if (growProgress > 0 && elapsed < 0) {
496
- animProgress = 0;
497
- }
481
+ // Icons track the global growProgress directly (no stagger)
482
+ // This keeps them in sync with the building heights
498
483
  const minHeight = 0.3;
499
484
  const baseOffset = 0.2;
500
- const height = animProgress * targetHeight + minHeight;
485
+ const height = growProgress * targetHeight + minHeight;
501
486
  const buildingTop = height + baseOffset;
502
- // When flat (animProgress=0): icon lies flat at ground level
503
- // When grown (animProgress=1): icon floats above building
487
+ // When flat (growProgress=0): icon lies flat at ground level
488
+ // When grown (growProgress=1): icon lies flat above building roof
504
489
  const flatY = minHeight + baseOffset + 0.5;
505
- const grownY = buildingTop + iconSize / 2 + 2;
506
- const yPosition = flatY + (grownY - flatY) * animProgress;
490
+ const grownY = buildingTop + 0.5;
491
+ const yPosition = flatY + (grownY - flatY) * growProgress;
507
492
  meshRef.current.position.y = yPosition;
508
- // Rotate from flat (facing up) to upright (facing camera-ish)
509
- // Flat: -Math.PI / 2 (facing up)
510
- // Grown: 0 (facing forward)
511
- const flatRotationX = -Math.PI / 2;
512
- const grownRotationX = 0;
513
- meshRef.current.rotation.x = flatRotationX + (grownRotationX - flatRotationX) * animProgress;
493
+ // Keep icon flat (facing up) at all times
494
+ meshRef.current.rotation.x = -Math.PI / 2;
514
495
  if (materialRef.current) {
515
- // Show icons even when flat, fade out only slightly
516
- const minOpacity = 0.8;
517
- const effectiveOpacity = minOpacity + (1 - minOpacity) * animProgress;
518
- materialRef.current.opacity = opacity * effectiveOpacity;
496
+ materialRef.current.opacity = opacity;
519
497
  }
520
498
  });
521
499
  return (_jsxs("mesh", { ref: meshRef, position: [x, 0, z], scale: [iconSize, iconSize, 1], raycast: () => null, children: [_jsx("planeGeometry", { args: [1, 1] }), _jsx("meshBasicMaterial", { ref: materialRef, map: texture, transparent: true, opacity: 0.8, depthTest: true, depthWrite: false, side: THREE.DoubleSide })] }));
522
500
  }
523
- function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, linearScale, flatPatterns, highlightLayers, isolationMode, hasActiveHighlights, staggerIndices, springDuration, staggerDelay, }) {
501
+ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, linearScale, flatPatterns, highlightLayers, isolationMode, hasActiveHighlights, }) {
524
502
  // Pre-compute buildings with icons
525
503
  const buildingsWithIcons = useMemo(() => {
526
504
  return buildings
527
- .map((building, index) => {
505
+ .map((building) => {
528
506
  const config = getConfigForFile(building);
529
507
  if (!config.icon)
530
508
  return null;
@@ -533,14 +511,13 @@ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, l
533
511
  const shouldDim = hasActiveHighlights && !isHighlighted;
534
512
  const shouldHide = shouldDim && isolationMode === 'hide';
535
513
  const shouldCollapse = shouldDim && isolationMode === 'collapse';
536
- if (shouldHide)
514
+ // Hide icons for buildings that are hidden or collapsed
515
+ if (shouldHide || shouldCollapse)
537
516
  return null;
538
517
  const fullHeight = calculateBuildingHeight(building, heightScaling, linearScale, flatPatterns);
539
- const targetHeight = shouldCollapse ? 0.5 : fullHeight;
518
+ const targetHeight = fullHeight;
540
519
  const x = building.position.x - centerOffset.x;
541
520
  const z = building.position.z - centerOffset.z;
542
- const staggerIndex = staggerIndices[index] ?? index;
543
- const staggerDelayMs = staggerDelay * staggerIndex;
544
521
  return {
545
522
  building,
546
523
  config,
@@ -548,7 +525,6 @@ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, l
548
525
  z,
549
526
  targetHeight,
550
527
  shouldDim,
551
- staggerDelayMs,
552
528
  };
553
529
  })
554
530
  .filter(Boolean);
@@ -561,11 +537,9 @@ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, l
561
537
  heightScaling,
562
538
  linearScale,
563
539
  flatPatterns,
564
- staggerIndices,
565
- staggerDelay,
566
540
  ]);
567
541
  // Icons are now always rendered (flat or grown)
568
- return (_jsx(_Fragment, { children: buildingsWithIcons.map(({ building, config, x, z, targetHeight, shouldDim, staggerDelayMs }) => {
542
+ return (_jsx(_Fragment, { children: buildingsWithIcons.map(({ building, config, x, z, targetHeight, shouldDim }) => {
569
543
  const icon = config.icon;
570
544
  const texture = getIconTexture(icon.name, icon.color || '#ffffff');
571
545
  if (!texture)
@@ -575,7 +549,7 @@ function BuildingIcons({ buildings, centerOffset, growProgress, heightScaling, l
575
549
  const minDimension = Math.min(width, depth);
576
550
  const iconSize = minDimension * (icon.size || 0.6) * 1.7;
577
551
  const opacity = shouldDim && isolationMode === 'transparent' ? 0.3 : 1;
578
- return (_jsx(AnimatedIcon, { x: x, z: z, targetHeight: targetHeight, iconSize: iconSize, texture: texture, opacity: opacity, growProgress: growProgress, staggerDelayMs: staggerDelayMs, springDuration: springDuration }, building.path));
552
+ return (_jsx(AnimatedIcon, { x: x, z: z, targetHeight: targetHeight, iconSize: iconSize, texture: texture, opacity: opacity, growProgress: growProgress }, building.path));
579
553
  }) }));
580
554
  }
581
555
  function DistrictFloor({ district, centerOffset, highlightColor, growProgress }) {
@@ -599,10 +573,10 @@ function DistrictFloor({ district, centerOffset, highlightColor, growProgress })
599
573
  const flatY = 0.5;
600
574
  const grownY = 1.5;
601
575
  const textY = flatY + (grownY - flatY) * growProgress;
602
- const flatZ = 0; // Center of district when flat
603
- const grownZ = depth / 2 + 2; // Edge of district when grown
576
+ const flatZ = depth / 2 - 6; // Near bottom of district when flat, with padding
577
+ const grownZ = depth / 2 + 2; // Just outside edge when grown
604
578
  const textZ = flatZ + (grownZ - flatZ) * growProgress;
605
- return (_jsxs("group", { position: [centerX, 0, centerZ], children: [_jsxs("lineSegments", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY, 0], renderOrder: -1, children: [_jsx("edgesGeometry", { args: [new THREE.PlaneGeometry(width, depth)], attach: "geometry" }), _jsx("lineBasicMaterial", { color: borderColor, linewidth: lineWidth, depthWrite: false })] }), highlightColor && (_jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY - 0.1, 0], renderOrder: -2, children: [_jsx("planeGeometry", { args: [width, depth] }), _jsx("meshBasicMaterial", { color: highlightColor, transparent: true, opacity: 0.15, depthWrite: false })] })), district.label && (_jsx(Text, { position: [0, textY, textZ], rotation: [textRotationX, 0, 0], fontSize: Math.min(3, width / 6), color: labelColor, anchorX: "center", anchorY: "middle", outlineWidth: 0.1, outlineColor: "#0f172a", children: dirName }))] }));
579
+ return (_jsxs("group", { position: [centerX, 0, centerZ], children: [_jsxs("lineSegments", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY, 0], renderOrder: -1, children: [_jsx("edgesGeometry", { args: [new THREE.PlaneGeometry(width, depth)], attach: "geometry" }), _jsx("lineBasicMaterial", { color: borderColor, linewidth: lineWidth, depthWrite: false })] }), highlightColor && (_jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], position: [0, floorY - 0.1, 0], renderOrder: -2, children: [_jsx("planeGeometry", { args: [width, depth] }), _jsx("meshBasicMaterial", { color: highlightColor, transparent: true, opacity: 0.15, depthWrite: false })] })), _jsx(Text, { position: [0, textY, textZ], rotation: [textRotationX, 0, 0], fontSize: Math.max(6, Math.min(12, width / 3)), color: labelColor, anchorX: "center", anchorY: "middle", outlineWidth: 0.15, outlineColor: "#0f172a", children: dirName })] }));
606
580
  }
607
581
  let cameraApi = null;
608
582
  export function resetCamera() {
@@ -1354,7 +1328,7 @@ function CityScene({ cityData, onBuildingHover, onBuildingClick, hoveredBuilding
1354
1328
  // Focus color takes priority, then highlight layer color
1355
1329
  const districtColor = (isFocused && buildingFocusColor) ? buildingFocusColor : highlightLayerColor;
1356
1330
  return (_jsx(DistrictFloor, { district: district, centerOffset: centerOffset, opacity: 1, highlightColor: districtColor, growProgress: growProgress }, district.path));
1357
- }), _jsx(InstancedBuildings, { buildings: cityData.buildings, centerOffset: centerOffset, onHover: onBuildingHover, onClick: onBuildingClick, hoveredIndex: hoveredIndex, selectedIndex: selectedIndex, growProgress: growProgress, animationConfig: animationConfig, heightScaling: heightScaling, linearScale: linearScale, flatPatterns: flatPatterns, staggerIndices: staggerIndices, focusDirectory: buildingFocusDirectory, highlightLayers: highlightLayers, isolationMode: isolationMode }), _jsx(BuildingIcons, { buildings: cityData.buildings, centerOffset: centerOffset, growProgress: growProgress, heightScaling: heightScaling, linearScale: linearScale, flatPatterns: flatPatterns, highlightLayers: highlightLayers, isolationMode: isolationMode, hasActiveHighlights: activeHighlights, staggerIndices: staggerIndices, springDuration: springDuration, staggerDelay: animationConfig.staggerDelay || 15 })] }));
1331
+ }), _jsx(InstancedBuildings, { buildings: cityData.buildings, centerOffset: centerOffset, onHover: onBuildingHover, onClick: onBuildingClick, hoveredIndex: hoveredIndex, selectedIndex: selectedIndex, growProgress: growProgress, animationConfig: animationConfig, heightScaling: heightScaling, linearScale: linearScale, flatPatterns: flatPatterns, staggerIndices: staggerIndices, focusDirectory: buildingFocusDirectory, highlightLayers: highlightLayers, isolationMode: isolationMode }), _jsx(BuildingIcons, { buildings: cityData.buildings, centerOffset: centerOffset, growProgress: growProgress, heightScaling: heightScaling, linearScale: linearScale, flatPatterns: flatPatterns, highlightLayers: highlightLayers, isolationMode: isolationMode, hasActiveHighlights: activeHighlights })] }));
1358
1332
  }
1359
1333
  /**
1360
1334
  * FileCity3D - 3D visualization of codebase structure
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/file-city-react",
3
- "version": "0.5.24",
3
+ "version": "0.5.26",
4
4
  "type": "module",
5
5
  "description": "React components for File City visualization",
6
6
  "main": "dist/index.js",
@@ -769,9 +769,6 @@ interface BuildingIconsProps {
769
769
  highlightLayers: HighlightLayer[];
770
770
  isolationMode: IsolationMode;
771
771
  hasActiveHighlights: boolean;
772
- staggerIndices: number[];
773
- springDuration: number;
774
- staggerDelay: number;
775
772
  }
776
773
 
777
774
  // Individual animated icon component
@@ -783,8 +780,6 @@ interface AnimatedIconProps {
783
780
  texture: THREE.Texture;
784
781
  opacity: number;
785
782
  growProgress: number;
786
- staggerDelayMs: number;
787
- springDuration: number;
788
783
  }
789
784
 
790
785
  function AnimatedIcon({
@@ -795,60 +790,33 @@ function AnimatedIcon({
795
790
  texture,
796
791
  opacity,
797
792
  growProgress,
798
- staggerDelayMs,
799
- springDuration,
800
793
  }: AnimatedIconProps) {
801
794
  const meshRef = useRef<THREE.Mesh>(null);
802
- const startTimeRef = useRef<number | null>(null);
803
795
  const materialRef = useRef<THREE.MeshBasicMaterial>(null);
804
796
 
805
- useFrame(({ clock }) => {
797
+ useFrame(() => {
806
798
  if (!meshRef.current) return;
807
799
 
808
- if (startTimeRef.current === null && growProgress > 0) {
809
- startTimeRef.current = clock.elapsedTime * 1000;
810
- }
811
-
812
- const currentTime = clock.elapsedTime * 1000;
813
- const animStartTime = startTimeRef.current ?? currentTime;
814
-
815
- // Calculate per-icon animation progress
816
- const elapsed = currentTime - animStartTime - staggerDelayMs;
817
- let animProgress = growProgress;
818
-
819
- if (growProgress > 0 && elapsed >= 0) {
820
- const t = Math.min(elapsed / springDuration, 1);
821
- const eased = 1 - Math.pow(1 - t, 3);
822
- animProgress = eased * growProgress;
823
- } else if (growProgress > 0 && elapsed < 0) {
824
- animProgress = 0;
825
- }
826
-
800
+ // Icons track the global growProgress directly (no stagger)
801
+ // This keeps them in sync with the building heights
827
802
  const minHeight = 0.3;
828
803
  const baseOffset = 0.2;
829
- const height = animProgress * targetHeight + minHeight;
804
+ const height = growProgress * targetHeight + minHeight;
830
805
  const buildingTop = height + baseOffset;
831
806
 
832
- // When flat (animProgress=0): icon lies flat at ground level
833
- // When grown (animProgress=1): icon floats above building
807
+ // When flat (growProgress=0): icon lies flat at ground level
808
+ // When grown (growProgress=1): icon lies flat above building roof
834
809
  const flatY = minHeight + baseOffset + 0.5;
835
- const grownY = buildingTop + iconSize / 2 + 2;
836
- const yPosition = flatY + (grownY - flatY) * animProgress;
810
+ const grownY = buildingTop + 0.5;
811
+ const yPosition = flatY + (grownY - flatY) * growProgress;
837
812
 
838
813
  meshRef.current.position.y = yPosition;
839
814
 
840
- // Rotate from flat (facing up) to upright (facing camera-ish)
841
- // Flat: -Math.PI / 2 (facing up)
842
- // Grown: 0 (facing forward)
843
- const flatRotationX = -Math.PI / 2;
844
- const grownRotationX = 0;
845
- meshRef.current.rotation.x = flatRotationX + (grownRotationX - flatRotationX) * animProgress;
815
+ // Keep icon flat (facing up) at all times
816
+ meshRef.current.rotation.x = -Math.PI / 2;
846
817
 
847
818
  if (materialRef.current) {
848
- // Show icons even when flat, fade out only slightly
849
- const minOpacity = 0.8;
850
- const effectiveOpacity = minOpacity + (1 - minOpacity) * animProgress;
851
- materialRef.current.opacity = opacity * effectiveOpacity;
819
+ materialRef.current.opacity = opacity;
852
820
  }
853
821
  });
854
822
 
@@ -883,14 +851,11 @@ function BuildingIcons({
883
851
  highlightLayers,
884
852
  isolationMode,
885
853
  hasActiveHighlights,
886
- staggerIndices,
887
- springDuration,
888
- staggerDelay,
889
854
  }: BuildingIconsProps) {
890
855
  // Pre-compute buildings with icons
891
856
  const buildingsWithIcons = useMemo(() => {
892
857
  return buildings
893
- .map((building, index) => {
858
+ .map((building) => {
894
859
  const config = getConfigForFile(building);
895
860
  if (!config.icon) return null;
896
861
 
@@ -900,17 +865,15 @@ function BuildingIcons({
900
865
  const shouldHide = shouldDim && isolationMode === 'hide';
901
866
  const shouldCollapse = shouldDim && isolationMode === 'collapse';
902
867
 
903
- if (shouldHide) return null;
868
+ // Hide icons for buildings that are hidden or collapsed
869
+ if (shouldHide || shouldCollapse) return null;
904
870
 
905
871
  const fullHeight = calculateBuildingHeight(building, heightScaling, linearScale, flatPatterns);
906
- const targetHeight = shouldCollapse ? 0.5 : fullHeight;
872
+ const targetHeight = fullHeight;
907
873
 
908
874
  const x = building.position.x - centerOffset.x;
909
875
  const z = building.position.z - centerOffset.z;
910
876
 
911
- const staggerIndex = staggerIndices[index] ?? index;
912
- const staggerDelayMs = staggerDelay * staggerIndex;
913
-
914
877
  return {
915
878
  building,
916
879
  config,
@@ -918,7 +881,6 @@ function BuildingIcons({
918
881
  z,
919
882
  targetHeight,
920
883
  shouldDim,
921
- staggerDelayMs,
922
884
  };
923
885
  })
924
886
  .filter(Boolean) as Array<{
@@ -928,7 +890,6 @@ function BuildingIcons({
928
890
  z: number;
929
891
  targetHeight: number;
930
892
  shouldDim: boolean;
931
- staggerDelayMs: number;
932
893
  }>;
933
894
  }, [
934
895
  buildings,
@@ -939,15 +900,13 @@ function BuildingIcons({
939
900
  heightScaling,
940
901
  linearScale,
941
902
  flatPatterns,
942
- staggerIndices,
943
- staggerDelay,
944
903
  ]);
945
904
 
946
905
  // Icons are now always rendered (flat or grown)
947
906
  return (
948
907
  <>
949
908
  {buildingsWithIcons.map(
950
- ({ building, config, x, z, targetHeight, shouldDim, staggerDelayMs }) => {
909
+ ({ building, config, x, z, targetHeight, shouldDim }) => {
951
910
  const icon = config.icon!;
952
911
  const texture = getIconTexture(icon.name, icon.color || '#ffffff');
953
912
  if (!texture) return null;
@@ -969,8 +928,6 @@ function BuildingIcons({
969
928
  texture={texture}
970
929
  opacity={opacity}
971
930
  growProgress={growProgress}
972
- staggerDelayMs={staggerDelayMs}
973
- springDuration={springDuration}
974
931
  />
975
932
  );
976
933
  },
@@ -1015,8 +972,8 @@ function DistrictFloor({ district, centerOffset, highlightColor, growProgress }:
1015
972
  const grownY = 1.5;
1016
973
  const textY = flatY + (grownY - flatY) * growProgress;
1017
974
 
1018
- const flatZ = 0; // Center of district when flat
1019
- const grownZ = depth / 2 + 2; // Edge of district when grown
975
+ const flatZ = depth / 2 - 6; // Near bottom of district when flat, with padding
976
+ const grownZ = depth / 2 + 2; // Just outside edge when grown
1020
977
  const textZ = flatZ + (grownZ - flatZ) * growProgress;
1021
978
 
1022
979
  return (
@@ -1035,20 +992,19 @@ function DistrictFloor({ district, centerOffset, highlightColor, growProgress }:
1035
992
  </mesh>
1036
993
  )}
1037
994
 
1038
- {district.label && (
1039
- <Text
1040
- position={[0, textY, textZ]}
1041
- rotation={[textRotationX, 0, 0]}
1042
- fontSize={Math.min(3, width / 6)}
1043
- color={labelColor}
1044
- anchorX="center"
1045
- anchorY="middle"
1046
- outlineWidth={0.1}
1047
- outlineColor="#0f172a"
1048
- >
1049
- {dirName}
1050
- </Text>
1051
- )}
995
+ {/* Always show directory name label */}
996
+ <Text
997
+ position={[0, textY, textZ]}
998
+ rotation={[textRotationX, 0, 0]}
999
+ fontSize={Math.max(6, Math.min(12, width / 3))}
1000
+ color={labelColor}
1001
+ anchorX="center"
1002
+ anchorY="middle"
1003
+ outlineWidth={0.15}
1004
+ outlineColor="#0f172a"
1005
+ >
1006
+ {dirName}
1007
+ </Text>
1052
1008
  </group>
1053
1009
  );
1054
1010
  }
@@ -2140,9 +2096,6 @@ function CityScene({
2140
2096
  highlightLayers={highlightLayers}
2141
2097
  isolationMode={isolationMode}
2142
2098
  hasActiveHighlights={activeHighlights}
2143
- staggerIndices={staggerIndices}
2144
- springDuration={springDuration}
2145
- staggerDelay={animationConfig.staggerDelay || 15}
2146
2099
  />
2147
2100
  </>
2148
2101
  );