fix(move-events): fire for panOnScroll

This commit is contained in:
moklick
2023-08-16 10:51:55 +02:00
parent 3122d06987
commit 258244f368
5 changed files with 93 additions and 48 deletions
@@ -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,
+45 -12
View File
@@ -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 (