fix(move-events): fire for panOnScroll
This commit is contained in:
@@ -26,6 +26,8 @@ export type ZoomPanValues = {
|
||||
prevViewport: Viewport;
|
||||
mouseButton: number;
|
||||
timerId: ReturnType<typeof setTimeout> | undefined;
|
||||
panScrollTimeout: ReturnType<typeof setTimeout> | undefined;
|
||||
isPanScrolling: boolean;
|
||||
};
|
||||
|
||||
export function XYPanZoom({
|
||||
@@ -46,6 +48,8 @@ export function XYPanZoom({
|
||||
prevViewport: { x: 0, y: 0, zoom: 0 },
|
||||
mouseButton: 0,
|
||||
timerId: undefined,
|
||||
panScrollTimeout: undefined,
|
||||
isPanScrolling: false,
|
||||
};
|
||||
const bbox = domNode.getBoundingClientRect();
|
||||
const d3ZoomInstance = zoom().scaleExtent([minZoom, maxZoom]).translateExtent(translateExtent);
|
||||
@@ -98,12 +102,16 @@ export function XYPanZoom({
|
||||
|
||||
const wheelHandler = isPanOnScroll
|
||||
? createPanOnScrollHandler({
|
||||
zoomPanValues,
|
||||
noWheelClassName,
|
||||
d3Selection,
|
||||
d3Zoom: d3ZoomInstance,
|
||||
panOnScrollMode,
|
||||
panOnScrollSpeed,
|
||||
zoomOnPinch,
|
||||
onPanZoomStart,
|
||||
onPanZoom,
|
||||
onPanZoomEnd,
|
||||
})
|
||||
: createZoomOnScrollHandler({
|
||||
noWheelClassName,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import type { D3ZoomEvent } from 'd3-zoom';
|
||||
import { pointer } from 'd3-selection';
|
||||
@@ -8,28 +9,24 @@ import {
|
||||
type D3ZoomHandler,
|
||||
type D3ZoomInstance,
|
||||
type OnPanZoom,
|
||||
type Viewport,
|
||||
type OnDraggingChange,
|
||||
type OnTransformChange,
|
||||
} from '../types';
|
||||
import { isRightClickPan, isWrappedWithClass, transformToViewport, viewChanged, wheelDelta } from './utils';
|
||||
import { clamp, isMacOs } from '../utils';
|
||||
|
||||
export type ZoomPanValues = {
|
||||
isZoomingOrPanning: boolean;
|
||||
usedRightMouseButton: boolean;
|
||||
prevViewport: Viewport;
|
||||
mouseButton: number;
|
||||
timerId: ReturnType<typeof setTimeout> | undefined;
|
||||
};
|
||||
import { isMacOs } from '../utils';
|
||||
import { ZoomPanValues } from './XYPanZoom';
|
||||
|
||||
export type PanOnScrollParams = {
|
||||
zoomPanValues: ZoomPanValues;
|
||||
noWheelClassName: string;
|
||||
d3Selection: D3SelectionInstance;
|
||||
d3Zoom: D3ZoomInstance;
|
||||
panOnScrollMode: PanOnScrollMode;
|
||||
panOnScrollSpeed: number;
|
||||
zoomOnPinch: boolean;
|
||||
onPanZoomStart?: OnPanZoom;
|
||||
onPanZoom?: OnPanZoom;
|
||||
onPanZoomEnd?: OnPanZoom;
|
||||
};
|
||||
|
||||
export type ZoomOnScrollParams = {
|
||||
@@ -62,12 +59,16 @@ export type PanZoomEndParams = {
|
||||
};
|
||||
|
||||
export function createPanOnScrollHandler({
|
||||
zoomPanValues,
|
||||
noWheelClassName,
|
||||
d3Selection,
|
||||
d3Zoom,
|
||||
panOnScrollMode,
|
||||
panOnScrollSpeed,
|
||||
zoomOnPinch,
|
||||
onPanZoomStart,
|
||||
onPanZoom,
|
||||
onPanZoomEnd,
|
||||
}: PanOnScrollParams) {
|
||||
return (event: any) => {
|
||||
if (isWrappedWithClass(event, noWheelClassName)) {
|
||||
@@ -105,8 +106,33 @@ export function createPanOnScrollHandler({
|
||||
d3Zoom.translateBy(
|
||||
d3Selection,
|
||||
-(deltaX / currentZoom) * panOnScrollSpeed,
|
||||
-(deltaY / currentZoom) * panOnScrollSpeed
|
||||
-(deltaY / currentZoom) * panOnScrollSpeed,
|
||||
// @ts-ignore
|
||||
{ internal: true }
|
||||
);
|
||||
|
||||
const nextViewport = transformToViewport(d3Selection.property('__zoom'));
|
||||
|
||||
clearTimeout(zoomPanValues.panScrollTimeout);
|
||||
|
||||
// for pan on scroll we need to handle the event calls on our own
|
||||
// we can't use the start, zoom and end events from d3-zoom
|
||||
// because start and move gets called on every scroll event and not once at the beginning
|
||||
if (!zoomPanValues.isPanScrolling) {
|
||||
zoomPanValues.isPanScrolling = true;
|
||||
|
||||
onPanZoomStart?.(event, nextViewport);
|
||||
}
|
||||
|
||||
if (zoomPanValues.isPanScrolling) {
|
||||
onPanZoom?.(event, nextViewport);
|
||||
|
||||
zoomPanValues.panScrollTimeout = setTimeout(() => {
|
||||
onPanZoomEnd?.(event, nextViewport);
|
||||
|
||||
zoomPanValues.isPanScrolling = false;
|
||||
}, 150);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -124,6 +150,10 @@ export function createZoomOnScrollHandler({ noWheelClassName, preventScrolling,
|
||||
|
||||
export function createPanZoomStartHandler({ zoomPanValues, onDraggingChange, onPanZoomStart }: PanZoomStartParams) {
|
||||
return (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
if (event.sourceEvent?.internal) {
|
||||
return;
|
||||
}
|
||||
|
||||
const viewport = transformToViewport(event.transform);
|
||||
|
||||
// we need to remember it here, because it's always 0 in the "zoom" event
|
||||
@@ -155,7 +185,7 @@ export function createPanZoomHandler({
|
||||
|
||||
onTransformChange([event.transform.x, event.transform.y, event.transform.k]);
|
||||
|
||||
if (onPanZoom) {
|
||||
if (onPanZoom && !event.sourceEvent?.internal) {
|
||||
onPanZoom?.(event.sourceEvent as MouseEvent | TouchEvent, transformToViewport(event.transform));
|
||||
}
|
||||
};
|
||||
@@ -170,6 +200,9 @@ export function createPanZoomEndHandler({
|
||||
onPaneContextMenu,
|
||||
}: PanZoomEndParams) {
|
||||
return (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
if (event.sourceEvent?.internal) {
|
||||
return;
|
||||
}
|
||||
zoomPanValues.isZoomingOrPanning = false;
|
||||
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user