diff --git a/packages/system/src/types/general.ts b/packages/system/src/types/general.ts index 8ac3f9e9..1f6b2ecf 100644 --- a/packages/system/src/types/general.ts +++ b/packages/system/src/types/general.ts @@ -95,7 +95,8 @@ export type FitViewParamsBase = { * @inline */ export type FitViewOptionsBase = { - padding?: number; + padding?: number | [number, number]; + paddingUnit?: 'px' | '%'; includeHiddenNodes?: boolean; minZoom?: number; maxZoom?: number; diff --git a/packages/system/src/utils/general.ts b/packages/system/src/utils/general.ts index 32c339e5..90ff64fa 100644 --- a/packages/system/src/utils/general.ts +++ b/packages/system/src/utils/general.ts @@ -195,10 +195,16 @@ export const getViewportForBounds = ( height: number, minZoom: number, maxZoom: number, - padding: number + padding: number | [number, number], + paddingUnit: 'px' | '%' ): Viewport => { - const xZoom = width / (bounds.width * (1 + padding)); - const yZoom = height / (bounds.height * (1 + padding)); + const [paddingX, paddingY] = Array.isArray(padding) ? [padding[0], padding[1]] : [padding, padding]; + + const isPixelPadding = paddingUnit === 'px'; + + const xZoom = width / (isPixelPadding ? bounds.width + paddingX : bounds.width * (1 + paddingX)); + const yZoom = height / (isPixelPadding ? bounds.height + paddingY : bounds.height * (1 + paddingY)); + const zoom = Math.min(xZoom, yZoom); const clampedZoom = clamp(zoom, minZoom, maxZoom); const boundsCenterX = bounds.x + bounds.width / 2; diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts index e14f81cd..930c4adb 100644 --- a/packages/system/src/utils/graph.ts +++ b/packages/system/src/utils/graph.ts @@ -372,7 +372,8 @@ export async function fitViewport< height, options?.minZoom ?? minZoom, options?.maxZoom ?? maxZoom, - options?.padding ?? 0.1 + options?.padding ?? 0.1, + options?.paddingUnit ?? '%' ); await panZoom.setViewport(viewport, { duration: options?.duration });