175 lines
5.4 KiB
TypeScript
175 lines
5.4 KiB
TypeScript
export const WORKBENCH_LAYOUT = {
|
|
headerHeight: 56,
|
|
desktopMinWidth: 1024,
|
|
persistentConditionMinWidth: 1280,
|
|
wideMinWidth: 1536,
|
|
collapsedAgentWidth: 0,
|
|
collapsedAgentRailWidth: 64,
|
|
minAgentWidth: 400,
|
|
maxAgentWidth: 640,
|
|
agentPanelLeftInset: 12,
|
|
conditionPanelRightInset: 64,
|
|
minimumAgentMapCorridor: 256,
|
|
mapEdgeGap: 24,
|
|
desktop: {
|
|
agentWidth: 500,
|
|
conditionWidth: 432,
|
|
conditionExpandedWidth: 880,
|
|
toolbarWidth: 48,
|
|
tickerWidth: 420
|
|
},
|
|
wide: {
|
|
agentWidth: 540,
|
|
conditionWidth: 432,
|
|
conditionExpandedWidth: 960,
|
|
toolbarWidth: 48,
|
|
tickerWidth: 460
|
|
},
|
|
mobileSheet: {
|
|
halfViewportRatio: 0.52,
|
|
fullTopGap: 68
|
|
},
|
|
mobileOverlay: {
|
|
edgeInset: 12,
|
|
gap: 8,
|
|
dockHeight: 44,
|
|
timelineSummaryHeight: 48
|
|
}
|
|
} as const;
|
|
|
|
export function resolveMobileWorkbenchOverlayLayout(timelineVisible: boolean) {
|
|
const { edgeInset, gap, dockHeight, timelineSummaryHeight } = WORKBENCH_LAYOUT.mobileOverlay;
|
|
const dockBottom = timelineVisible ? edgeInset + timelineSummaryHeight + gap : edgeInset;
|
|
|
|
return {
|
|
timelineBottom: edgeInset,
|
|
dockBottom,
|
|
mapControlBottom: dockBottom + dockHeight + gap
|
|
};
|
|
}
|
|
|
|
export function clampAgentPanelWidth(
|
|
width: number,
|
|
viewportWidth: number,
|
|
conditionExpanded = false
|
|
) {
|
|
const maxWidth = getAgentPanelMaxWidth(viewportWidth, conditionExpanded);
|
|
|
|
return Math.round(
|
|
Math.min(Math.max(width, WORKBENCH_LAYOUT.minAgentWidth), maxWidth)
|
|
);
|
|
}
|
|
|
|
export function getAgentPanelDefaultWidth(viewportWidth: number, conditionExpanded = false) {
|
|
const layout = getWorkbenchViewportLayout(viewportWidth);
|
|
if (viewportWidth < WORKBENCH_LAYOUT.desktopMinWidth) {
|
|
return layout.agentWidth;
|
|
}
|
|
|
|
const conditionWidth = conditionExpanded ? layout.conditionExpandedWidth : layout.conditionWidth;
|
|
const collisionSafeWidth =
|
|
viewportWidth -
|
|
WORKBENCH_LAYOUT.agentPanelLeftInset -
|
|
WORKBENCH_LAYOUT.mapEdgeGap -
|
|
conditionWidth -
|
|
WORKBENCH_LAYOUT.mapEdgeGap -
|
|
layout.toolbarWidth;
|
|
|
|
return Math.min(layout.agentWidth, collisionSafeWidth);
|
|
}
|
|
|
|
export function getAgentPanelMaxWidth(viewportWidth: number, conditionExpanded = false) {
|
|
const layout = getWorkbenchViewportLayout(viewportWidth);
|
|
const conditionWidth = conditionExpanded ? layout.conditionExpandedWidth : layout.conditionWidth;
|
|
const widthWithMapCorridor =
|
|
viewportWidth -
|
|
WORKBENCH_LAYOUT.agentPanelLeftInset -
|
|
WORKBENCH_LAYOUT.conditionPanelRightInset -
|
|
conditionWidth -
|
|
WORKBENCH_LAYOUT.minimumAgentMapCorridor;
|
|
|
|
return Math.min(WORKBENCH_LAYOUT.maxAgentWidth, Math.max(layout.agentWidth, widthWithMapCorridor));
|
|
}
|
|
|
|
export type WorkbenchPanelState = {
|
|
agentOpen: boolean;
|
|
agentWidth?: number;
|
|
conditionOpen: boolean;
|
|
conditionExpanded?: boolean;
|
|
};
|
|
|
|
export type WorkbenchBasemapTone = "light" | "satellite" | "none";
|
|
|
|
export type WorkbenchViewportLayout = {
|
|
agentWidth: number;
|
|
conditionWidth: number;
|
|
conditionExpandedWidth: number;
|
|
toolbarWidth: number;
|
|
tickerWidth: number;
|
|
};
|
|
|
|
export function getWorkbenchViewportLayout(viewportWidth: number): WorkbenchViewportLayout {
|
|
return viewportWidth >= WORKBENCH_LAYOUT.wideMinWidth
|
|
? WORKBENCH_LAYOUT.wide
|
|
: WORKBENCH_LAYOUT.desktop;
|
|
}
|
|
|
|
export function getWorkbenchBasemapTone(activeBaseLayerId: string): WorkbenchBasemapTone {
|
|
if (["mapbox-light", "tianditu-vector"].includes(activeBaseLayerId)) {
|
|
return "light";
|
|
}
|
|
|
|
if (["mapbox-satellite", "tianditu-image"].includes(activeBaseLayerId)) {
|
|
return "satellite";
|
|
}
|
|
|
|
return "none";
|
|
}
|
|
|
|
export function getWorkbenchCameraPadding(viewportWidth: number, panels: WorkbenchPanelState) {
|
|
if (viewportWidth < WORKBENCH_LAYOUT.desktopMinWidth) {
|
|
return { top: 72, right: 24, bottom: 72, left: 24 };
|
|
}
|
|
|
|
const layout = getWorkbenchViewportLayout(viewportWidth);
|
|
const agentWidth = panels.agentOpen
|
|
? panels.agentWidth === undefined
|
|
? getAgentPanelDefaultWidth(
|
|
viewportWidth,
|
|
panels.conditionOpen && Boolean(panels.conditionExpanded)
|
|
)
|
|
: clampAgentPanelWidth(
|
|
panels.agentWidth,
|
|
viewportWidth,
|
|
panels.conditionOpen && Boolean(panels.conditionExpanded)
|
|
)
|
|
: WORKBENCH_LAYOUT.collapsedAgentWidth;
|
|
const conditionWidth = panels.conditionOpen
|
|
? panels.conditionExpanded
|
|
? layout.conditionExpandedWidth
|
|
: layout.conditionWidth
|
|
: 0;
|
|
|
|
return {
|
|
top: WORKBENCH_LAYOUT.headerHeight + 16,
|
|
right: WORKBENCH_LAYOUT.mapEdgeGap + layout.toolbarWidth + conditionWidth,
|
|
bottom: 32,
|
|
left: WORKBENCH_LAYOUT.mapEdgeGap + agentWidth
|
|
};
|
|
}
|
|
|
|
export function getWorkbenchLayoutCssVariables() {
|
|
return {
|
|
"--workbench-agent-width": `${WORKBENCH_LAYOUT.desktop.agentWidth}px`,
|
|
"--workbench-agent-width-wide": `${WORKBENCH_LAYOUT.wide.agentWidth}px`,
|
|
"--workbench-agent-rail-width": `${WORKBENCH_LAYOUT.collapsedAgentRailWidth}px`,
|
|
"--workbench-condition-width": `${WORKBENCH_LAYOUT.desktop.conditionWidth}px`,
|
|
"--workbench-condition-width-wide": `${WORKBENCH_LAYOUT.wide.conditionWidth}px`,
|
|
"--workbench-condition-expanded-width": `${WORKBENCH_LAYOUT.desktop.conditionExpandedWidth}px`,
|
|
"--workbench-condition-expanded-width-wide": `${WORKBENCH_LAYOUT.wide.conditionExpandedWidth}px`,
|
|
"--workbench-toolbar-width": `${WORKBENCH_LAYOUT.desktop.toolbarWidth}px`,
|
|
"--workbench-ticker-width": `${WORKBENCH_LAYOUT.desktop.tickerWidth}px`,
|
|
"--workbench-ticker-width-wide": `${WORKBENCH_LAYOUT.wide.tickerWidth}px`
|
|
} as const;
|
|
}
|