fix(scroll): fast zoom issue on windows with ctrl
This commit is contained in:
@@ -173,3 +173,5 @@ export const getTransformForBounds = (
|
|||||||
|
|
||||||
return [x, y, clampedZoom];
|
return [x, y, clampedZoom];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isMacOs = () => typeof navigator !== 'undefined' && navigator?.userAgent?.indexOf('Mac') >= 0;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
PanZoomInstance,
|
PanZoomInstance,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { clamp } from '../utils';
|
import { clamp } from '../utils';
|
||||||
import { getD3Transition, viewportToTransform } from './utils';
|
import { getD3Transition, viewportToTransform, wheelDelta } from './utils';
|
||||||
import {
|
import {
|
||||||
createPanOnScrollHandler,
|
createPanOnScrollHandler,
|
||||||
createPanZoomEndHandler,
|
createPanZoomEndHandler,
|
||||||
@@ -65,6 +65,7 @@ export function XYPanZoom({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const d3ZoomHandler = d3Selection.on('wheel.zoom')!;
|
const d3ZoomHandler = d3Selection.on('wheel.zoom')!;
|
||||||
|
d3ZoomInstance.wheelDelta(wheelDelta);
|
||||||
|
|
||||||
function setTransform(transform: ZoomTransform, options?: PanZoomTransformOptions) {
|
function setTransform(transform: ZoomTransform, options?: PanZoomTransformOptions) {
|
||||||
if (d3Selection) {
|
if (d3Selection) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
import type { D3ZoomEvent } from 'd3-zoom';
|
import type { D3ZoomEvent } from 'd3-zoom';
|
||||||
import { pointer } from 'd3-selection';
|
import { pointer } from 'd3-selection';
|
||||||
|
|
||||||
@@ -11,7 +12,8 @@ import {
|
|||||||
type OnDraggingChange,
|
type OnDraggingChange,
|
||||||
type OnTransformChange,
|
type OnTransformChange,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { isRightClickPan, isWrappedWithClass, transformToViewport, viewChanged } from './utils';
|
import { isRightClickPan, isWrappedWithClass, transformToViewport, viewChanged, wheelDelta } from './utils';
|
||||||
|
import { clamp, isMacOs } from '../utils';
|
||||||
|
|
||||||
export type ZoomPanValues = {
|
export type ZoomPanValues = {
|
||||||
isZoomingOrPanning: boolean;
|
isZoomingOrPanning: boolean;
|
||||||
@@ -75,13 +77,15 @@ export function createPanOnScrollHandler({
|
|||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
|
|
||||||
const currentZoom = d3Selection.property('__zoom').k || 1;
|
const currentZoom = d3Selection.property('__zoom').k || 1;
|
||||||
|
const _isMacOs = isMacOs();
|
||||||
|
|
||||||
if (event.ctrlKey && zoomOnPinch) {
|
// macos sets ctrlKey=true for pinch gesture on a trackpad
|
||||||
|
if (event.ctrlKey && zoomOnPinch && _isMacOs) {
|
||||||
const point = pointer(event);
|
const point = pointer(event);
|
||||||
// taken from https://github.com/d3/d3-zoom/blob/master/src/zoom.js
|
const pinchDelta = wheelDelta(event);
|
||||||
const pinchDelta = -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * 10;
|
|
||||||
const zoom = currentZoom * Math.pow(2, pinchDelta);
|
const zoom = currentZoom * Math.pow(2, pinchDelta);
|
||||||
d3Zoom.scaleTo(d3Selection, zoom, point);
|
// @ts-ignore
|
||||||
|
d3Zoom.scaleTo(d3Selection, zoom, point, event);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -89,8 +93,14 @@ export function createPanOnScrollHandler({
|
|||||||
// 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;
|
||||||
const deltaX = panOnScrollMode === PanOnScrollMode.Vertical ? 0 : event.deltaX * deltaNormalize;
|
let deltaX = panOnScrollMode === PanOnScrollMode.Vertical ? 0 : event.deltaX * deltaNormalize;
|
||||||
const deltaY = panOnScrollMode === PanOnScrollMode.Horizontal ? 0 : event.deltaY * deltaNormalize;
|
let deltaY = panOnScrollMode === PanOnScrollMode.Horizontal ? 0 : event.deltaY * deltaNormalize;
|
||||||
|
|
||||||
|
// this enables vertical scrolling with shift + scroll on windows
|
||||||
|
if (!_isMacOs && event.shiftKey && panOnScrollMode !== PanOnScrollMode.Vertical) {
|
||||||
|
deltaX = event.deltaY * deltaNormalize;
|
||||||
|
deltaY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
d3Zoom.translateBy(
|
d3Zoom.translateBy(
|
||||||
d3Selection,
|
d3Selection,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { type ZoomTransform, zoomIdentity } from 'd3-zoom';
|
import { type ZoomTransform, zoomIdentity } from 'd3-zoom';
|
||||||
|
|
||||||
import { type D3SelectionInstance, type Viewport } from '../types';
|
import { type D3SelectionInstance, type Viewport } from '../types';
|
||||||
|
import { isMacOs } from '../utils';
|
||||||
|
|
||||||
export const viewChanged = (prevViewport: Viewport, eventViewport: any): boolean =>
|
export const viewChanged = (prevViewport: Viewport, eventViewport: any): boolean =>
|
||||||
prevViewport.x !== eventViewport.x || prevViewport.y !== eventViewport.y || prevViewport.zoom !== eventViewport.k;
|
prevViewport.x !== eventViewport.x || prevViewport.y !== eventViewport.y || prevViewport.zoom !== eventViewport.k;
|
||||||
@@ -21,3 +22,9 @@ export const isRightClickPan = (panOnDrag: boolean | number[], usedButton: numbe
|
|||||||
|
|
||||||
export const getD3Transition = (selection: D3SelectionInstance, duration = 0) =>
|
export const getD3Transition = (selection: D3SelectionInstance, duration = 0) =>
|
||||||
typeof duration === 'number' && duration > 0 ? selection.transition().duration(duration) : selection;
|
typeof duration === 'number' && duration > 0 ? selection.transition().duration(duration) : selection;
|
||||||
|
|
||||||
|
export const wheelDelta = (event: any) => {
|
||||||
|
const factor = event.ctrlKey && isMacOs() ? 10 : 1;
|
||||||
|
|
||||||
|
return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * factor;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user