feat(zoomPanHelper): add fitBounds func
This commit is contained in:
@@ -4,7 +4,7 @@ import { zoomIdentity } from 'd3-zoom';
|
|||||||
import { useStoreState, useStore } from '../store/hooks';
|
import { useStoreState, useStore } from '../store/hooks';
|
||||||
import { clamp } from '../utils';
|
import { clamp } from '../utils';
|
||||||
import { getRectOfNodes } from '../utils/graph';
|
import { getRectOfNodes } from '../utils/graph';
|
||||||
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions } from '../types';
|
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions, Rect, Transform } from '../types';
|
||||||
|
|
||||||
const initialZoomPanHelper: ZoomPanHelperFunctions = {
|
const initialZoomPanHelper: ZoomPanHelperFunctions = {
|
||||||
zoomIn: () => {},
|
zoomIn: () => {},
|
||||||
@@ -13,9 +13,30 @@ const initialZoomPanHelper: ZoomPanHelperFunctions = {
|
|||||||
transform: (_: FlowTransform) => {},
|
transform: (_: FlowTransform) => {},
|
||||||
fitView: (_: FitViewParams = { padding: 0.1 }) => {},
|
fitView: (_: FitViewParams = { padding: 0.1 }) => {},
|
||||||
setCenter: (_: number, __: number) => {},
|
setCenter: (_: number, __: number) => {},
|
||||||
|
fitBounds: (_: Rect) => {},
|
||||||
initialized: false,
|
initialized: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTransformForBounds = (
|
||||||
|
bounds: Rect,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
minZoom: number,
|
||||||
|
maxZoom: number,
|
||||||
|
padding = 0.1
|
||||||
|
): Transform => {
|
||||||
|
const xZoom = width / (bounds.width * (1 + padding));
|
||||||
|
const yZoom = height / (bounds.height * (1 + padding));
|
||||||
|
const zoom = Math.min(xZoom, yZoom);
|
||||||
|
const clampedZoom = clamp(zoom, minZoom, maxZoom);
|
||||||
|
const boundsCenterX = bounds.x + bounds.width / 2;
|
||||||
|
const boundsCenterY = bounds.y + bounds.height / 2;
|
||||||
|
const x = width / 2 - boundsCenterX * clampedZoom;
|
||||||
|
const y = height / 2 - boundsCenterY * clampedZoom;
|
||||||
|
|
||||||
|
return [x, y, zoom];
|
||||||
|
};
|
||||||
|
|
||||||
const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const d3Zoom = useStoreState((s) => s.d3Zoom);
|
const d3Zoom = useStoreState((s) => s.d3Zoom);
|
||||||
@@ -40,15 +61,8 @@ const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bounds = getRectOfNodes(nodes);
|
const bounds = getRectOfNodes(nodes);
|
||||||
const xZoom = width / (bounds.width * (1 + options.padding));
|
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, options.padding);
|
||||||
const yZoom = height / (bounds.height * (1 + options.padding));
|
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
||||||
const zoom = Math.min(xZoom, yZoom);
|
|
||||||
const clampedZoom = clamp(zoom, minZoom, maxZoom);
|
|
||||||
const boundsCenterX = bounds.x + bounds.width / 2;
|
|
||||||
const boundsCenterY = bounds.y + bounds.height / 2;
|
|
||||||
const x = width / 2 - boundsCenterX * clampedZoom;
|
|
||||||
const y = height / 2 - boundsCenterY * clampedZoom;
|
|
||||||
const transform = zoomIdentity.translate(x, y).scale(clampedZoom);
|
|
||||||
|
|
||||||
d3Zoom.transform(d3Selection, transform);
|
d3Zoom.transform(d3Selection, transform);
|
||||||
},
|
},
|
||||||
@@ -62,6 +76,13 @@ const usePanZoomHelper = (): ZoomPanHelperFunctions => {
|
|||||||
|
|
||||||
d3Zoom.transform(d3Selection, transform);
|
d3Zoom.transform(d3Selection, transform);
|
||||||
},
|
},
|
||||||
|
fitBounds: (bounds: Rect, padding = 0.1) => {
|
||||||
|
const { width, height, minZoom, maxZoom } = store.getState();
|
||||||
|
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
|
||||||
|
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
||||||
|
|
||||||
|
d3Zoom.transform(d3Selection, transform);
|
||||||
|
},
|
||||||
initialized: true,
|
initialized: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ export interface ZoomPanHelperFunctions {
|
|||||||
transform: (transform: FlowTransform) => void;
|
transform: (transform: FlowTransform) => void;
|
||||||
fitView: (params?: FitViewParams) => void;
|
fitView: (params?: FitViewParams) => void;
|
||||||
setCenter: (x: number, y: number, zoom?: number) => void;
|
setCenter: (x: number, y: number, zoom?: number) => void;
|
||||||
|
fitBounds: (bounds: Rect, padding?: number) => void;
|
||||||
initialized: boolean;
|
initialized: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user