refactor(minimap): cleanup events when not pannable or zoomable
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { memo, useEffect, useRef } from 'react';
|
import { memo, useEffect, useRef } from 'react';
|
||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
@@ -41,12 +42,12 @@ const ARIA_LABEL_KEY = 'react-flow__minimap-desc';
|
|||||||
function MiniMap({
|
function MiniMap({
|
||||||
style,
|
style,
|
||||||
className,
|
className,
|
||||||
nodeStrokeColor = '#555',
|
nodeStrokeColor = 'transparent',
|
||||||
nodeColor = '#fff',
|
nodeColor = '#e2e2e2',
|
||||||
nodeClassName = '',
|
nodeClassName = '',
|
||||||
nodeBorderRadius = 5,
|
nodeBorderRadius = 5,
|
||||||
nodeStrokeWidth = 2,
|
nodeStrokeWidth = 2,
|
||||||
maskColor = 'rgb(240, 242, 243, 0.7)',
|
maskColor = 'rgb(240, 240, 240, 0.6)',
|
||||||
position = 'bottom-right',
|
position = 'bottom-right',
|
||||||
onClick,
|
onClick,
|
||||||
onNodeClick,
|
onNodeClick,
|
||||||
@@ -81,43 +82,50 @@ function MiniMap({
|
|||||||
if (svg.current) {
|
if (svg.current) {
|
||||||
const selection = select(svg.current as Element);
|
const selection = select(svg.current as Element);
|
||||||
|
|
||||||
const zoomHandler = zoom()
|
const zoomHandler = (event: D3ZoomEvent<SVGSVGElement, any>) => {
|
||||||
.on('zoom.wheel', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
const { transform, d3Selection, d3Zoom } = store.getState();
|
||||||
const { transform, d3Selection, d3Zoom } = store.getState();
|
|
||||||
|
|
||||||
if (event.sourceEvent.type !== 'wheel' || !zoomable || !d3Selection || !d3Zoom) {
|
if (event.sourceEvent.type !== 'wheel' || !d3Selection || !d3Zoom) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
10;
|
||||||
const zoom = transform[2] * Math.pow(2, pinchDelta);
|
const zoom = transform[2] * Math.pow(2, pinchDelta);
|
||||||
|
|
||||||
d3Zoom.scaleTo(d3Selection, zoom);
|
d3Zoom.scaleTo(d3Selection, zoom);
|
||||||
})
|
};
|
||||||
.on('zoom', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
|
||||||
const { transform, d3Selection, d3Zoom } = store.getState();
|
|
||||||
|
|
||||||
if (event.sourceEvent.type !== 'mousemove' || !pannable || !d3Selection || !d3Zoom) {
|
const panHandler = (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||||
return;
|
const { transform, d3Selection, d3Zoom } = store.getState();
|
||||||
}
|
|
||||||
|
|
||||||
// @TODO: how to calculate the correct next position? Math.max(1, transform[2]) is a workaround.
|
if (event.sourceEvent.type !== 'mousemove' || !d3Selection || !d3Zoom) {
|
||||||
const position = {
|
return;
|
||||||
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 nextTransform = zoomIdentity.translate(position.x, position.y).scale(transform[2]);
|
// @TODO: how to calculate the correct next position? Math.max(1, transform[2]) is a workaround.
|
||||||
|
const position = {
|
||||||
|
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]),
|
||||||
|
};
|
||||||
|
|
||||||
d3Zoom.transform(d3Selection, nextTransform);
|
const nextTransform = zoomIdentity.translate(position.x, position.y).scale(transform[2]);
|
||||||
});
|
|
||||||
selection.call(zoomHandler);
|
d3Zoom.transform(d3Selection, nextTransform);
|
||||||
|
};
|
||||||
|
|
||||||
|
const zoomAndPanHandler = zoom()
|
||||||
|
// @ts-ignore
|
||||||
|
.on('zoom', pannable ? panHandler : null)
|
||||||
|
// @ts-ignore
|
||||||
|
.on('zoom.wheel', zoomable ? zoomHandler : null);
|
||||||
|
|
||||||
|
selection.call(zoomAndPanHandler);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
selection.on('.zoom', null);
|
selection.on('zoom', null);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [pannable, zoomable]);
|
}, [pannable, zoomable]);
|
||||||
|
|||||||
Reference in New Issue
Block a user