feat(interaction): add zoomToPinch prop

This commit is contained in:
moklick
2021-01-21 10:58:54 +01:00
parent 83ac0787d8
commit f7a400f216
5 changed files with 45 additions and 4 deletions
+14
View File
@@ -27,6 +27,7 @@ const InteractionFlow = () => {
const [isDraggable, setIsDraggable] = useState(false); const [isDraggable, setIsDraggable] = useState(false);
const [isConnectable, setIsConnectable] = useState(false); const [isConnectable, setIsConnectable] = useState(false);
const [zoomOnScroll, setZoomOnScroll] = useState(false); const [zoomOnScroll, setZoomOnScroll] = useState(false);
const [zoomOnPinch, setZoomOnPinch] = useState(false);
const [panOnScroll, setPanOnScroll] = useState(false); const [panOnScroll, setPanOnScroll] = useState(false);
const [panOnScrollMode, setPanOnScrollMode] = useState('free'); const [panOnScrollMode, setPanOnScrollMode] = useState('free');
const [zoomOnDoubleClick, setZoomOnDoubleClick] = useState(false); const [zoomOnDoubleClick, setZoomOnDoubleClick] = useState(false);
@@ -42,6 +43,7 @@ const InteractionFlow = () => {
nodesConnectable={isConnectable} nodesConnectable={isConnectable}
nodesDraggable={isDraggable} nodesDraggable={isDraggable}
zoomOnScroll={zoomOnScroll} zoomOnScroll={zoomOnScroll}
zoomOnPinch={zoomOnPinch}
panOnScroll={panOnScroll} panOnScroll={panOnScroll}
panOnScrollMode={panOnScrollMode} panOnScrollMode={panOnScrollMode}
zoomOnDoubleClick={zoomOnDoubleClick} zoomOnDoubleClick={zoomOnDoubleClick}
@@ -107,6 +109,18 @@ const InteractionFlow = () => {
/> />
</label> </label>
</div> </div>
<div>
<label htmlFor="zoomonpinch">
zoomOnPinch
<input
id="zoomonpinch"
type="checkbox"
checked={zoomOnPinch}
onChange={(event) => setZoomOnPinch(event.target.checked)}
className="react-flow__zoomonpinch"
/>
</label>
</div>
<div> <div>
<label htmlFor="panonscroll"> <label htmlFor="panonscroll">
panOnScroll panOnScroll
+2
View File
@@ -40,6 +40,7 @@ const FlowRenderer = ({
zoomActivationKeyCode, zoomActivationKeyCode,
elementsSelectable, elementsSelectable,
zoomOnScroll, zoomOnScroll,
zoomOnPinch,
panOnScroll, panOnScroll,
panOnScrollSpeed, panOnScrollSpeed,
panOnScrollMode, panOnScrollMode,
@@ -92,6 +93,7 @@ const FlowRenderer = ({
selectionKeyPressed={selectionKeyPressed} selectionKeyPressed={selectionKeyPressed}
elementsSelectable={elementsSelectable} elementsSelectable={elementsSelectable}
zoomOnScroll={zoomOnScroll} zoomOnScroll={zoomOnScroll}
zoomOnPinch={zoomOnPinch}
panOnScroll={panOnScroll} panOnScroll={panOnScroll}
panOnScrollSpeed={panOnScrollSpeed} panOnScrollSpeed={panOnScrollSpeed}
panOnScrollMode={panOnScrollMode} panOnScrollMode={panOnScrollMode}
+2
View File
@@ -73,6 +73,7 @@ const GraphView = ({
arrowHeadColor, arrowHeadColor,
markerEndId, markerEndId,
zoomOnScroll, zoomOnScroll,
zoomOnPinch,
panOnScroll, panOnScroll,
panOnScrollSpeed, panOnScrollSpeed,
panOnScrollMode, panOnScrollMode,
@@ -212,6 +213,7 @@ const GraphView = ({
onMoveStart={onMoveStart} onMoveStart={onMoveStart}
onMoveEnd={onMoveEnd} onMoveEnd={onMoveEnd}
zoomOnScroll={zoomOnScroll} zoomOnScroll={zoomOnScroll}
zoomOnPinch={zoomOnPinch}
zoomOnDoubleClick={zoomOnDoubleClick} zoomOnDoubleClick={zoomOnDoubleClick}
panOnScroll={panOnScroll} panOnScroll={panOnScroll}
panOnScrollSpeed={panOnScrollSpeed} panOnScrollSpeed={panOnScrollSpeed}
+3
View File
@@ -100,6 +100,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
arrowHeadColor?: string; arrowHeadColor?: string;
markerEndId?: string; markerEndId?: string;
zoomOnScroll?: boolean; zoomOnScroll?: boolean;
zoomOnPinch?: boolean;
panOnScroll?: boolean; panOnScroll?: boolean;
panOnScrollSpeed?: number; panOnScrollSpeed?: number;
panOnScrollMode?: PanOnScrollMode; panOnScrollMode?: PanOnScrollMode;
@@ -156,6 +157,7 @@ const ReactFlow = ({
arrowHeadColor = '#b1b1b7', arrowHeadColor = '#b1b1b7',
markerEndId, markerEndId,
zoomOnScroll = true, zoomOnScroll = true,
zoomOnPinch = true,
panOnScroll = false, panOnScroll = false,
panOnScrollSpeed = 0.5, panOnScrollSpeed = 0.5,
panOnScrollMode = PanOnScrollMode.Free, panOnScrollMode = PanOnScrollMode.Free,
@@ -217,6 +219,7 @@ const ReactFlow = ({
arrowHeadColor={arrowHeadColor} arrowHeadColor={arrowHeadColor}
markerEndId={markerEndId} markerEndId={markerEndId}
zoomOnScroll={zoomOnScroll} zoomOnScroll={zoomOnScroll}
zoomOnPinch={zoomOnPinch}
zoomOnDoubleClick={zoomOnDoubleClick} zoomOnDoubleClick={zoomOnDoubleClick}
panOnScroll={panOnScroll} panOnScroll={panOnScroll}
panOnScrollSpeed={panOnScrollSpeed} panOnScrollSpeed={panOnScrollSpeed}
+24 -4
View File
@@ -1,6 +1,6 @@
import React, { useEffect, useRef, ReactNode } from 'react'; import React, { useEffect, useRef, ReactNode } from 'react';
import { zoom, zoomIdentity } from 'd3-zoom'; import { zoom, zoomIdentity } from 'd3-zoom';
import { select } from 'd3-selection'; import { select, pointer } from 'd3-selection';
import { clamp } from '../../utils'; import { clamp } from '../../utils';
import useKeyPress from '../../hooks/useKeyPress'; import useKeyPress from '../../hooks/useKeyPress';
@@ -12,6 +12,7 @@ interface ZoomPaneProps {
selectionKeyPressed: boolean; selectionKeyPressed: boolean;
elementsSelectable?: boolean; elementsSelectable?: boolean;
zoomOnScroll?: boolean; zoomOnScroll?: boolean;
zoomOnPinch?: boolean;
panOnScroll?: boolean; panOnScroll?: boolean;
panOnScrollSpeed?: number; panOnScrollSpeed?: number;
panOnScrollMode?: PanOnScrollMode; panOnScrollMode?: PanOnScrollMode;
@@ -43,6 +44,7 @@ const ZoomPane = ({
onMoveStart, onMoveStart,
onMoveEnd, onMoveEnd,
zoomOnScroll = true, zoomOnScroll = true,
zoomOnPinch = true,
panOnScroll = false, panOnScroll = false,
panOnScrollSpeed = 0.5, panOnScrollSpeed = 0.5,
panOnScrollMode = PanOnScrollMode.Free, panOnScrollMode = PanOnScrollMode.Free,
@@ -104,6 +106,17 @@ const ZoomPane = ({
event.stopImmediatePropagation(); event.stopImmediatePropagation();
const currentZoom = d3Selection.property('__zoom').k || 1; const currentZoom = d3Selection.property('__zoom').k || 1;
if (event.ctrlKey && zoomOnPinch) {
const point = pointer(event);
// taken from https://github.com/d3/d3-zoom/blob/master/src/zoom.js
const pinchDelta = -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * 10;
const zoom = currentZoom * Math.pow(2, pinchDelta);
d3Zoom.scaleTo(d3Selection, zoom, point);
return;
}
// increase scroll speed in firefox // increase scroll speed in firefox
// firefox: deltaMode === 1; chrome: deltaMode === 0 // firefox: deltaMode === 1; chrome: deltaMode === 0
const deltaNormalize = event.deltaMode === 1 ? 20 : 1; const deltaNormalize = event.deltaMode === 1 ? 20 : 1;
@@ -121,7 +134,7 @@ const ZoomPane = ({
d3Selection.on('wheel', null).on('wheel.zoom', d3ZoomHandler); d3Selection.on('wheel', null).on('wheel.zoom', d3ZoomHandler);
} }
} }
}, [panOnScroll, panOnScrollMode, d3Selection, d3Zoom, d3ZoomHandler, zoomActivationKeyPressed]); }, [panOnScroll, panOnScrollMode, d3Selection, d3Zoom, d3ZoomHandler, zoomActivationKeyPressed, zoomOnPinch]);
useEffect(() => { useEffect(() => {
if (d3Zoom) { if (d3Zoom) {
@@ -178,8 +191,10 @@ const ZoomPane = ({
if (d3Zoom) { if (d3Zoom) {
d3Zoom.filter((event: any) => { d3Zoom.filter((event: any) => {
const zoomScroll = zoomActivationKeyPressed || zoomOnScroll; const zoomScroll = zoomActivationKeyPressed || zoomOnScroll;
const pinchZoom = zoomOnPinch && event.ctrlKey;
// if all interactions are disabled, we prevent all zoom events // if all interactions are disabled, we prevent all zoom events
if (!paneMoveable && !zoomScroll && !panOnScroll && !zoomOnDoubleClick) { if (!paneMoveable && !zoomScroll && !panOnScroll && !zoomOnDoubleClick && !zoomOnPinch) {
return false; return false;
} }
@@ -210,8 +225,12 @@ const ZoomPane = ({
return false; return false;
} }
if (!zoomOnPinch && event.ctrlKey && event.type === 'wheel') {
return false;
}
// when there is no scroll handling enabled, we prevent all wheel events // when there is no scroll handling enabled, we prevent all wheel events
if (!zoomScroll && !panOnScroll && event.type === 'wheel') { if (!zoomScroll && !panOnScroll && !pinchZoom && event.type === 'wheel') {
return false; return false;
} }
@@ -227,6 +246,7 @@ const ZoomPane = ({
}, [ }, [
d3Zoom, d3Zoom,
zoomOnScroll, zoomOnScroll,
zoomOnPinch,
panOnScroll, panOnScroll,
zoomOnDoubleClick, zoomOnDoubleClick,
paneMoveable, paneMoveable,