@principal-ai/principal-view-react 0.13.30 → 0.14.1

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.
@@ -55,6 +55,61 @@ export function getCanvasBounds(canvas: ExtendedCanvas): CanvasBounds {
55
55
  };
56
56
  }
57
57
 
58
+ export interface Viewport {
59
+ x: number;
60
+ y: number;
61
+ zoom: number;
62
+ }
63
+
64
+ /**
65
+ * Calculate the initial viewport to fit all nodes within a container.
66
+ * This allows setting defaultViewport on ReactFlow to avoid the
67
+ * "zoom in then animate out" effect.
68
+ *
69
+ * @param bounds - The bounding box of all nodes
70
+ * @param containerWidth - Width of the container in pixels
71
+ * @param containerHeight - Height of the container in pixels
72
+ * @param options - Additional options for padding and zoom limits
73
+ * @returns The viewport { x, y, zoom } to pass to ReactFlow's defaultViewport
74
+ */
75
+ export function calculateInitialViewport(
76
+ bounds: CanvasBounds,
77
+ containerWidth: number,
78
+ containerHeight: number,
79
+ options: {
80
+ padding?: number;
81
+ minZoom?: number;
82
+ maxZoom?: number;
83
+ } = {}
84
+ ): Viewport {
85
+ const { padding = 0.2, minZoom = 0.1, maxZoom = 1.5 } = options;
86
+
87
+ // Calculate the zoom level needed to fit the bounds within the container
88
+ // Account for padding by reducing the effective container size
89
+ const effectiveWidth = containerWidth * (1 - padding);
90
+ const effectiveHeight = containerHeight * (1 - padding);
91
+
92
+ const zoomX = effectiveWidth / bounds.width;
93
+ const zoomY = effectiveHeight / bounds.height;
94
+
95
+ // Use the smaller zoom to ensure both dimensions fit
96
+ let zoom = Math.min(zoomX, zoomY);
97
+
98
+ // Clamp to min/max zoom
99
+ zoom = Math.max(minZoom, Math.min(maxZoom, zoom));
100
+
101
+ // Calculate the center of the bounds
102
+ const boundsCenterX = bounds.minX + bounds.width / 2;
103
+ const boundsCenterY = bounds.minY + bounds.height / 2;
104
+
105
+ // Calculate viewport position to center the bounds
106
+ // ReactFlow viewport x,y represent the offset of the canvas origin from the container's top-left
107
+ const x = containerWidth / 2 - boundsCenterX * zoom;
108
+ const y = containerHeight / 2 - boundsCenterY * zoom;
109
+
110
+ return { x, y, zoom };
111
+ }
112
+
58
113
  /**
59
114
  * Calculate a recommended display size for a canvas cell.
60
115
  * Adds padding and enforces minimum dimensions.