feat(react/svelte): controlled viewport (#3461)
* feat(react): controlled viewport * refactor(react): cleanup viewport * feat(svelte): two way data binding for viewport, cleanup transform <> viewport stuff * refactor(svelte): viewport stuff
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { ZoomTransform } from 'd3-zoom';
|
||||
import type { ZoomTransform } from 'd3-zoom';
|
||||
|
||||
import { CoordinateExtent, PanOnScrollMode, Transform, Viewport } from './';
|
||||
import { PanOnScrollMode, type CoordinateExtent, type Transform, type Viewport } from './';
|
||||
|
||||
export type OnDraggingChange = (dragging: boolean) => void;
|
||||
export type OnTransformChange = (transform: Transform) => void;
|
||||
@@ -55,4 +55,5 @@ export type PanZoomInstance = {
|
||||
setTranslateExtent: (translateExtent: CoordinateExtent) => void;
|
||||
scaleTo: (scale: number, options?: PanZoomTransformOptions) => void;
|
||||
scaleBy: (factor: number, options?: PanZoomTransformOptions) => void;
|
||||
syncViewport: (viewport: Viewport) => void;
|
||||
};
|
||||
|
||||
@@ -194,6 +194,22 @@ export function XYPanZoom({
|
||||
return nextTransform;
|
||||
}
|
||||
|
||||
function syncViewport(viewport: Viewport) {
|
||||
if (d3Selection) {
|
||||
const nextTransform = viewportToTransform(viewport);
|
||||
const currentTransform = d3Selection.property('__zoom');
|
||||
|
||||
if (
|
||||
currentTransform.k !== viewport.zoom ||
|
||||
currentTransform.x !== viewport.x ||
|
||||
currentTransform.y !== viewport.y
|
||||
) {
|
||||
// @ts-ignore
|
||||
d3ZoomInstance?.transform(d3Selection, nextTransform, null, { sync: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getViewport(): Viewport {
|
||||
const transform = d3Selection ? zoomTransform(d3Selection.node() as Element) : { x: 0, y: 0, k: 1 };
|
||||
return { x: transform.x, y: transform.y, zoom: transform.k };
|
||||
@@ -229,5 +245,6 @@ export function XYPanZoom({
|
||||
scaleBy,
|
||||
setScaleExtent,
|
||||
setTranslateExtent,
|
||||
syncViewport,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -183,7 +183,9 @@ export function createPanZoomHandler({
|
||||
onPaneContextMenu && isRightClickPan(panOnDrag, zoomPanValues.mouseButton ?? 0)
|
||||
);
|
||||
|
||||
onTransformChange([event.transform.x, event.transform.y, event.transform.k]);
|
||||
if (!event.sourceEvent?.sync) {
|
||||
onTransformChange([event.transform.x, event.transform.y, event.transform.k]);
|
||||
}
|
||||
|
||||
if (onPanZoom && !event.sourceEvent?.internal) {
|
||||
onPanZoom?.(event.sourceEvent as MouseEvent | TouchEvent, transformToViewport(event.transform));
|
||||
|
||||
Reference in New Issue
Block a user