From 01e45bcda429ebcc02af5d7b7c25b5bcd10e5cf7 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 18 May 2026 11:01:00 +0100 Subject: [PATCH] Expose graph viewport backdrop --- .../src/lib/EpiphanyGraphViewer.tsx | 55 ++++++++++++++----- web/epiphany-graph-viewer/src/lib/types.ts | 2 + 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/web/epiphany-graph-viewer/src/lib/EpiphanyGraphViewer.tsx b/web/epiphany-graph-viewer/src/lib/EpiphanyGraphViewer.tsx index 1a205b2..b85ae04 100644 --- a/web/epiphany-graph-viewer/src/lib/EpiphanyGraphViewer.tsx +++ b/web/epiphany-graph-viewer/src/lib/EpiphanyGraphViewer.tsx @@ -46,6 +46,8 @@ export function EpiphanyGraphViewer({ sidebarWidth = 330, showSidebar = true, overlayPanels = false, + viewportBackdrop, + viewportBackground, focusSelection = false, expandedNode, onExpandedNodeClick, @@ -238,8 +240,8 @@ export function EpiphanyGraphViewer({ return; } + const targetScale = focusedNodeScale(selectedNode, viewportSize.width, viewportSize.height); const center = nodeCenter(selectedNode); - const targetScale = clamp(transforms[activeGraphKey].scale, 0.72, 1.08); setTransforms((current) => ({ ...current, [activeGraphKey]: { @@ -386,14 +388,17 @@ export function EpiphanyGraphViewer({ overscrollBehavior: "contain", touchAction: "none", borderRadius: overlayPanels ? 0 : 28, - background: + background: viewportBackground ?? ( activeGraphKey === "architecture" ? "radial-gradient(circle at top left, rgba(8, 145, 178, 0.22), transparent 38%), linear-gradient(160deg, #08111e 0%, #0c1624 46%, #11192c 100%)" - : "radial-gradient(circle at top right, rgba(244, 63, 94, 0.18), transparent 34%), linear-gradient(160deg, #0b1018 0%, #15111c 44%, #1a0d18 100%)", + : "radial-gradient(circle at top right, rgba(244, 63, 94, 0.18), transparent 34%), linear-gradient(160deg, #0b1018 0%, #15111c 44%, #1a0d18 100%)" + ), border: overlayPanels ? "none" : PANEL_BORDER, boxShadow: overlayPanels ? "none" : "0 18px 54px rgba(0, 0, 0, 0.3)", }} > + {viewportBackdrop} +
= 680 && height >= 420 && areaRatio >= 0.22) { + return "article"; + } + + if (width >= 360 && height >= 190 && areaRatio >= 0.07) { + return "preview"; + } + + return "summary"; +} + function handleNativeWheel( event: WheelEvent, viewportElement: HTMLElement, @@ -1411,7 +1438,7 @@ function handleNativeWheel( const cursorY = event.clientY - rect.top; const current = transforms[graphKey]; const zoomFactor = event.deltaY < 0 ? 1.12 : 1 / 1.12; - const nextScale = clamp(current.scale * zoomFactor, 0.28, 5.4); + const nextScale = clamp(current.scale * zoomFactor, 0.28, 16); const worldX = (cursorX - current.x) / current.scale; const worldY = (cursorY - current.y) / current.scale; const nextX = cursorX - worldX * nextScale; @@ -1502,7 +1529,7 @@ function nudgeZoom( ...current, [graphKey]: { ...current[graphKey], - scale: clamp(current[graphKey].scale * factor, 0.28, 5.4), + scale: clamp(current[graphKey].scale * factor, 0.28, 16), userMoved: true, }, })); diff --git a/web/epiphany-graph-viewer/src/lib/types.ts b/web/epiphany-graph-viewer/src/lib/types.ts index 83d877a..02ae03c 100644 --- a/web/epiphany-graph-viewer/src/lib/types.ts +++ b/web/epiphany-graph-viewer/src/lib/types.ts @@ -83,6 +83,8 @@ export interface EpiphanyGraphViewerProps { sidebarWidth?: CSSProperties["width"]; showSidebar?: boolean; overlayPanels?: boolean; + viewportBackdrop?: ReactNode; + viewportBackground?: CSSProperties["background"]; focusSelection?: boolean; expandedNode?: { graphKey: GraphKey;