Merge pull request #2955 from wbkd/feat/minimap-inverse-pan-and-zoom-step
Feat/minimap inverse pan and zoom step
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@reactflow/minimap': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
add inversePan and zoomStep props
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MouseEvent, useCallback } from 'react';
|
import { MouseEvent, useCallback, useState } from 'react';
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
MiniMap,
|
MiniMap,
|
||||||
Background,
|
Background,
|
||||||
@@ -87,6 +87,7 @@ const defaultEdgeOptions = { zIndex: 0 };
|
|||||||
|
|
||||||
const BasicFlow = () => {
|
const BasicFlow = () => {
|
||||||
const instance = useReactFlow();
|
const instance = useReactFlow();
|
||||||
|
const [inverse, setInverse] = useState(false);
|
||||||
|
|
||||||
const updatePos = () => {
|
const updatePos = () => {
|
||||||
instance.setNodes((nodes) =>
|
instance.setNodes((nodes) =>
|
||||||
@@ -103,6 +104,7 @@ const BasicFlow = () => {
|
|||||||
|
|
||||||
const logToObject = () => console.log(instance.toObject());
|
const logToObject = () => console.log(instance.toObject());
|
||||||
const resetTransform = () => instance.setViewport({ x: 0, y: 0, zoom: 1 });
|
const resetTransform = () => instance.setViewport({ x: 0, y: 0, zoom: 1 });
|
||||||
|
const toggleInverse = () => setInverse(!inverse);
|
||||||
|
|
||||||
const toggleClassnames = () => {
|
const toggleClassnames = () => {
|
||||||
instance.setNodes((nodes) =>
|
instance.setNodes((nodes) =>
|
||||||
@@ -137,7 +139,8 @@ const BasicFlow = () => {
|
|||||||
fitView
|
fitView
|
||||||
>
|
>
|
||||||
<Background variant={BackgroundVariant.Dots} />
|
<Background variant={BackgroundVariant.Dots} />
|
||||||
<MiniMap onClick={onMiniMapClick} onNodeClick={onMiniMapNodeClick} pannable zoomable />
|
<MiniMap onClick={onMiniMapClick} onNodeClick={onMiniMapNodeClick} pannable zoomable
|
||||||
|
inversePan={inverse}/>
|
||||||
<Controls />
|
<Controls />
|
||||||
|
|
||||||
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||||
@@ -150,7 +153,12 @@ const BasicFlow = () => {
|
|||||||
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
|
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
|
||||||
toggle classnames
|
toggle classnames
|
||||||
</button>
|
</button>
|
||||||
<button onClick={logToObject}>toObject</button>
|
<button onClick={logToObject} style={{ marginRight: 5 }}>
|
||||||
|
toObject
|
||||||
|
</button>
|
||||||
|
<button onClick={toggleInverse} style={{ marginRight: 5 }}>
|
||||||
|
{inverse ? 'un-inverse pan' : 'inverse pan'}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ function MiniMap({
|
|||||||
pannable = false,
|
pannable = false,
|
||||||
zoomable = false,
|
zoomable = false,
|
||||||
ariaLabel = 'React Flow mini map',
|
ariaLabel = 'React Flow mini map',
|
||||||
|
inversePan = false,
|
||||||
|
zoomStep = 10
|
||||||
}: MiniMapProps) {
|
}: MiniMapProps) {
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const svg = useRef<SVGSVGElement>(null);
|
const svg = useRef<SVGSVGElement>(null);
|
||||||
@@ -106,7 +108,7 @@ function MiniMap({
|
|||||||
const pinchDelta =
|
const pinchDelta =
|
||||||
-event.sourceEvent.deltaY *
|
-event.sourceEvent.deltaY *
|
||||||
(event.sourceEvent.deltaMode === 1 ? 0.05 : event.sourceEvent.deltaMode ? 1 : 0.002) *
|
(event.sourceEvent.deltaMode === 1 ? 0.05 : event.sourceEvent.deltaMode ? 1 : 0.002) *
|
||||||
10;
|
zoomStep;
|
||||||
const zoom = transform[2] * Math.pow(2, pinchDelta);
|
const zoom = transform[2] * Math.pow(2, pinchDelta);
|
||||||
|
|
||||||
d3Zoom.scaleTo(d3Selection, zoom);
|
d3Zoom.scaleTo(d3Selection, zoom);
|
||||||
@@ -120,9 +122,10 @@ function MiniMap({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: how to calculate the correct next position? Math.max(1, transform[2]) is a workaround.
|
// @TODO: how to calculate the correct next position? Math.max(1, transform[2]) is a workaround.
|
||||||
|
const moveScale = viewScaleRef.current * Math.max(1, transform[2]) * (inversePan ? -1 : 1);
|
||||||
const position = {
|
const position = {
|
||||||
x: transform[0] - event.sourceEvent.movementX * viewScaleRef.current * Math.max(1, transform[2]),
|
x: transform[0] - event.sourceEvent.movementX * moveScale,
|
||||||
y: transform[1] - event.sourceEvent.movementY * viewScaleRef.current * Math.max(1, transform[2]),
|
y: transform[1] - event.sourceEvent.movementY * moveScale,
|
||||||
};
|
};
|
||||||
const extent: CoordinateExtent = [
|
const extent: CoordinateExtent = [
|
||||||
[0, 0],
|
[0, 0],
|
||||||
@@ -147,7 +150,7 @@ function MiniMap({
|
|||||||
selection.on('zoom', null);
|
selection.on('zoom', null);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [pannable, zoomable]);
|
}, [pannable, zoomable, inversePan, zoomStep]);
|
||||||
|
|
||||||
const onSvgClick = onClick
|
const onSvgClick = onClick
|
||||||
? (event: MouseEvent) => {
|
? (event: MouseEvent) => {
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ export type MiniMapProps<NodeData = any> = Omit<HTMLAttributes<SVGSVGElement>, '
|
|||||||
pannable?: boolean;
|
pannable?: boolean;
|
||||||
zoomable?: boolean;
|
zoomable?: boolean;
|
||||||
ariaLabel?: string | null;
|
ariaLabel?: string | null;
|
||||||
|
inversePan?: boolean;
|
||||||
|
zoomStep?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface MiniMapNodeProps {
|
export interface MiniMapNodeProps {
|
||||||
|
|||||||
Reference in New Issue
Block a user