All files / src/components/world/entities/scenes/hooks useSceneLabelOffsets.ts

0% Statements 0/37
0% Branches 0/22
0% Functions 0/10
0% Lines 0/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87                                                                                                                                                                             
import { useMemo } from "react";
import clamp from "shared/lib/helpers/clamp";
import { sceneSelectors } from "store/features/entities/entitiesSelectors";
import { useAppSelector } from "store/hooks";
 
const TILE_SIZE = 8;
const MIN_LABEL_WIDTH = 160;
 
const calculateLabelOffsets = (
  sceneX: number,
  sceneWidthPx: number,
  viewBoundsX: number,
  viewBoundsWidth: number,
) => {
  const maxOffset = Math.max(0, sceneWidthPx - MIN_LABEL_WIDTH);
  const left = viewBoundsX - sceneX;
  const right = sceneX + sceneWidthPx - (viewBoundsX + viewBoundsWidth);
  return {
    left: clamp(left, 0, maxOffset),
    right: clamp(right, 0, maxOffset),
  };
};
 
export const useSceneLabelOffsets = (sceneId: string) => {
  const sceneX = useAppSelector(
    (state) => sceneSelectors.selectById(state, sceneId)?.x ?? 0,
  );
 
  const sceneWidth = useAppSelector(
    (state) => sceneSelectors.selectById(state, sceneId)?.width ?? 0,
  );
 
  const worldScrollX = useAppSelector((state) => state.editor.worldScrollX);
 
  const worldViewWidth = useAppSelector((state) => state.editor.worldViewWidth);
 
  const sidebarWidth = useAppSelector(
    (state) => state.editor.worldSidebarWidth,
  );
 
  const navigatorWidth = useAppSelector((state) =>
    state.project.present.settings.showNavigator
      ? state.editor.navigatorSidebarWidth
      : 0,
  );
 
  const zoomRatio = useAppSelector((state) => state.editor.zoom / 100);
 
  return useMemo(() => {
    Iif (sceneWidth <= 0 || zoomRatio <= 0) {
      return {
        left: 0,
        right: 0,
      };
    }
 
    const sceneWidthPx = sceneWidth * TILE_SIZE;
    const viewBoundsX = worldScrollX / zoomRatio;
    const viewBoundsWidth =
      (worldViewWidth - sidebarWidth - navigatorWidth) / zoomRatio;
 
    const shouldOffsetLabels = sceneWidthPx > viewBoundsWidth / 2;
 
    Iif (!shouldOffsetLabels) {
      return {
        left: 0,
        right: 0,
      };
    }
 
    return calculateLabelOffsets(
      sceneX,
      sceneWidthPx,
      viewBoundsX,
      viewBoundsWidth,
    );
  }, [
    sceneX,
    sceneWidth,
    worldScrollX,
    worldViewWidth,
    sidebarWidth,
    navigatorWidth,
    zoomRatio,
  ]);
};