Merge pull request #2659 from wbkd/fix/translate-extent
fix(minimap): use translateExtent on pan
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@reactflow/core': patch
|
||||
'@reactflow/minimap': patch
|
||||
---
|
||||
|
||||
Use translateExtent correctly
|
||||
@@ -5,13 +5,12 @@ import type { D3ZoomEvent } from 'd3-zoom';
|
||||
import { select, pointer } from 'd3-selection';
|
||||
import shallow from 'zustand/shallow';
|
||||
|
||||
import { clamp } from '../../utils';
|
||||
import useKeyPress from '../../hooks/useKeyPress';
|
||||
import useResizeHandler from '../../hooks/useResizeHandler';
|
||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||
import { containerStyle } from '../../styles';
|
||||
import type { FlowRendererProps } from '../FlowRenderer';
|
||||
import { PanOnScrollMode } from '../../types';
|
||||
import { CoordinateExtent, PanOnScrollMode } from '../../types';
|
||||
import type { Viewport, ReactFlowState } from '../../types';
|
||||
|
||||
type ZoomPaneProps = Omit<
|
||||
@@ -71,22 +70,24 @@ const ZoomPane = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (zoomPane.current) {
|
||||
const bbox = zoomPane.current.getBoundingClientRect();
|
||||
const d3ZoomInstance = zoom().scaleExtent([minZoom, maxZoom]).translateExtent(translateExtent);
|
||||
const selection = select(zoomPane.current as Element).call(d3ZoomInstance);
|
||||
const updatedTransform = zoomIdentity.translate(defaultViewport.x, defaultViewport.y).scale(defaultViewport.zoom);
|
||||
const extent: CoordinateExtent = [
|
||||
[0, 0],
|
||||
[bbox.width, bbox.height],
|
||||
];
|
||||
|
||||
const clampedX = clamp(defaultViewport.x, translateExtent[0][0], translateExtent[1][0]);
|
||||
const clampedY = clamp(defaultViewport.y, translateExtent[0][1], translateExtent[1][1]);
|
||||
const clampedZoom = clamp(defaultViewport.zoom, minZoom, maxZoom);
|
||||
const updatedTransform = zoomIdentity.translate(clampedX, clampedY).scale(clampedZoom);
|
||||
|
||||
d3ZoomInstance.transform(selection, updatedTransform);
|
||||
const constrainedTransform = d3ZoomInstance.constrain()(updatedTransform, extent, translateExtent);
|
||||
d3ZoomInstance.transform(selection, constrainedTransform);
|
||||
|
||||
store.setState({
|
||||
d3Zoom: d3ZoomInstance,
|
||||
d3Selection: selection,
|
||||
d3ZoomHandler: selection.on('wheel.zoom'),
|
||||
// we need to pass transform because zoom handler is not registered when we set the initial transform
|
||||
transform: [clampedX, clampedY, clampedZoom],
|
||||
transform: [constrainedTransform.x, constrainedTransform.y, constrainedTransform.k],
|
||||
domNode: zoomPane.current.closest('.react-flow') as HTMLDivElement,
|
||||
});
|
||||
}
|
||||
@@ -156,7 +157,6 @@ const ZoomPane = ({
|
||||
} else if (!selectionKeyPressed) {
|
||||
d3Zoom.on('zoom', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
const { onViewportChange } = store.getState();
|
||||
|
||||
store.setState({ transform: [event.transform.x, event.transform.y, event.transform.k] });
|
||||
|
||||
if (onMove || onViewportChange) {
|
||||
|
||||
@@ -212,8 +212,7 @@ const createRFStore = () =>
|
||||
set({ maxZoom });
|
||||
},
|
||||
setTranslateExtent: (translateExtent: CoordinateExtent) => {
|
||||
const { d3Zoom } = get();
|
||||
d3Zoom?.translateExtent(translateExtent);
|
||||
get().d3Zoom?.translateExtent(translateExtent);
|
||||
|
||||
set({ translateExtent });
|
||||
},
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
getBoundsOfRects,
|
||||
useStoreApi,
|
||||
getNodePositionWithOrigin,
|
||||
CoordinateExtent,
|
||||
} from '@reactflow/core';
|
||||
import type { ReactFlowState, Rect } from '@reactflow/core';
|
||||
|
||||
@@ -109,7 +110,7 @@ function MiniMap({
|
||||
};
|
||||
|
||||
const panHandler = (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
const { transform, d3Selection, d3Zoom } = store.getState();
|
||||
const { transform, d3Selection, d3Zoom, translateExtent, width, height } = store.getState();
|
||||
|
||||
if (event.sourceEvent.type !== 'mousemove' || !d3Selection || !d3Zoom) {
|
||||
return;
|
||||
@@ -120,10 +121,15 @@ function MiniMap({
|
||||
x: transform[0] - event.sourceEvent.movementX * viewScaleRef.current * Math.max(1, transform[2]),
|
||||
y: transform[1] - event.sourceEvent.movementY * viewScaleRef.current * Math.max(1, transform[2]),
|
||||
};
|
||||
const extent: CoordinateExtent = [
|
||||
[0, 0],
|
||||
[width, height],
|
||||
];
|
||||
|
||||
const nextTransform = zoomIdentity.translate(position.x, position.y).scale(transform[2]);
|
||||
const constrainedTransform = d3Zoom.constrain()(nextTransform, extent, translateExtent);
|
||||
|
||||
d3Zoom.transform(d3Selection, nextTransform);
|
||||
d3Zoom.transform(d3Selection, constrainedTransform);
|
||||
};
|
||||
|
||||
const zoomAndPanHandler = zoom()
|
||||
|
||||
Reference in New Issue
Block a user