mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(editor): Zoom in/out on canvas the same amount on scroll/gesture (#7602)
Github issue / Community forum post (link here to close automatically): https://community.n8n.io/t/ctrl-mousewheel-zoom-jumps-out-possible-to-avoid/31952
This commit is contained in:
parent
0bd4e742da
commit
c92402a3ca
|
@ -16,11 +16,11 @@ const NDVDialog = new NDV();
|
||||||
const DEFAULT_ZOOM_FACTOR = 1;
|
const DEFAULT_ZOOM_FACTOR = 1;
|
||||||
const ZOOM_IN_X1_FACTOR = 1.25; // Zoom in factor after one click
|
const ZOOM_IN_X1_FACTOR = 1.25; // Zoom in factor after one click
|
||||||
const ZOOM_IN_X2_FACTOR = 1.5625; // Zoom in factor after two clicks
|
const ZOOM_IN_X2_FACTOR = 1.5625; // Zoom in factor after two clicks
|
||||||
const ZOOM_OUT_X1_FACTOR = 0.75;
|
const ZOOM_OUT_X1_FACTOR = 0.8;
|
||||||
const ZOOM_OUT_X2_FACTOR = 0.5625;
|
const ZOOM_OUT_X2_FACTOR = 0.64;
|
||||||
|
|
||||||
const PINCH_ZOOM_IN_FACTOR = 1.32;
|
const PINCH_ZOOM_IN_FACTOR = 1.05702;
|
||||||
const PINCH_ZOOM_OUT_FACTOR = 0.4752;
|
const PINCH_ZOOM_OUT_FACTOR = 0.946058;
|
||||||
const RENAME_NODE_NAME = 'Something else';
|
const RENAME_NODE_NAME = 'Something else';
|
||||||
|
|
||||||
describe('Canvas Node Manipulation and Navigation', () => {
|
describe('Canvas Node Manipulation and Navigation', () => {
|
||||||
|
@ -222,8 +222,8 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should zoom using pinch to zoom', () => {
|
it('should zoom using scroll or pinch gesture', () => {
|
||||||
WorkflowPage.actions.pinchToZoom(2, 'zoomIn');
|
WorkflowPage.actions.pinchToZoom(1, 'zoomIn');
|
||||||
WorkflowPage.getters
|
WorkflowPage.getters
|
||||||
.nodeView()
|
.nodeView()
|
||||||
.should(
|
.should(
|
||||||
|
@ -232,7 +232,11 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||||
`matrix(${PINCH_ZOOM_IN_FACTOR}, 0, 0, ${PINCH_ZOOM_IN_FACTOR}, 0, 0)`,
|
`matrix(${PINCH_ZOOM_IN_FACTOR}, 0, 0, ${PINCH_ZOOM_IN_FACTOR}, 0, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
WorkflowPage.actions.pinchToZoom(4, 'zoomOut');
|
WorkflowPage.actions.pinchToZoom(1, 'zoomOut');
|
||||||
|
// Zoom in 1x + Zoom out 1x should reset to default (=1)
|
||||||
|
WorkflowPage.getters.nodeView().should('have.css', 'transform', `matrix(1, 0, 0, 1, 0, 0)`);
|
||||||
|
|
||||||
|
WorkflowPage.actions.pinchToZoom(1, 'zoomOut');
|
||||||
WorkflowPage.getters
|
WorkflowPage.getters
|
||||||
.nodeView()
|
.nodeView()
|
||||||
.should(
|
.should(
|
||||||
|
|
|
@ -265,7 +265,8 @@ export class WorkflowPage extends BasePage {
|
||||||
ctrlKey: true,
|
ctrlKey: true,
|
||||||
pageX: cy.window().innerWidth / 2,
|
pageX: cy.window().innerWidth / 2,
|
||||||
pageY: cy.window().innerHeight / 2,
|
pageY: cy.window().innerHeight / 2,
|
||||||
deltaY: mode === 'zoomOut' ? 16 * steps : -16 * steps,
|
deltaMode: 1,
|
||||||
|
deltaY: mode === 'zoomOut' ? steps : -steps,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
hitUndo: () => {
|
hitUndo: () => {
|
||||||
|
|
|
@ -13,10 +13,11 @@ import type { Route } from 'vue-router';
|
||||||
'@/utils'.
|
'@/utils'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const SCALE_INCREASE_FACTOR = 1.25;
|
const SCALE_CHANGE_FACTOR = 1.25;
|
||||||
const SCALE_DECREASE_FACTOR = 0.75;
|
|
||||||
const MIN_SCALE = 0.2;
|
const MIN_SCALE = 0.2;
|
||||||
const MAX_SCALE = 5;
|
const MAX_SCALE = 5;
|
||||||
|
const SCROLL_ZOOM_SPEED = 0.01;
|
||||||
|
const MAX_WHEEL_DELTA = 32;
|
||||||
|
|
||||||
const clamp = (min: number, max: number) => (num: number) => {
|
const clamp = (min: number, max: number) => (num: number) => {
|
||||||
return Math.max(min, Math.min(max, num));
|
return Math.max(min, Math.min(max, num));
|
||||||
|
@ -43,9 +44,9 @@ export const applyScale =
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const scaleBigger = applyScale(SCALE_INCREASE_FACTOR);
|
export const scaleBigger = applyScale(SCALE_CHANGE_FACTOR);
|
||||||
|
|
||||||
export const scaleSmaller = applyScale(SCALE_DECREASE_FACTOR);
|
export const scaleSmaller = applyScale(1 / SCALE_CHANGE_FACTOR);
|
||||||
|
|
||||||
export const scaleReset = (config: IZoomConfig): IZoomConfig => {
|
export const scaleReset = (config: IZoomConfig): IZoomConfig => {
|
||||||
return applyScale(1 / config.scale)(config);
|
return applyScale(1 / config.scale)(config);
|
||||||
|
@ -108,6 +109,8 @@ export const getConnectionInfo = (
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clampWheelDelta = clamp(-MAX_WHEEL_DELTA, MAX_WHEEL_DELTA);
|
||||||
|
|
||||||
export const normalizeWheelEventDelta = (event: WheelEvent): { deltaX: number; deltaY: number } => {
|
export const normalizeWheelEventDelta = (event: WheelEvent): { deltaX: number; deltaY: number } => {
|
||||||
const factorByMode: Record<number, number> = {
|
const factorByMode: Record<number, number> = {
|
||||||
[WheelEvent.DOM_DELTA_PIXEL]: 1,
|
[WheelEvent.DOM_DELTA_PIXEL]: 1,
|
||||||
|
@ -117,9 +120,12 @@ export const normalizeWheelEventDelta = (event: WheelEvent): { deltaX: number; d
|
||||||
|
|
||||||
const factor = factorByMode[event.deltaMode] ?? 1;
|
const factor = factorByMode[event.deltaMode] ?? 1;
|
||||||
|
|
||||||
return { deltaX: event.deltaX * factor, deltaY: event.deltaY * factor };
|
return {
|
||||||
|
deltaX: clampWheelDelta(event.deltaX * factor),
|
||||||
|
deltaY: clampWheelDelta(event.deltaY * factor),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getScaleFromWheelEventDelta = (delta: number): number => {
|
export const getScaleFromWheelEventDelta = (delta: number): number => {
|
||||||
return 1 - delta / 100;
|
return Math.pow(2, -delta * SCROLL_ZOOM_SPEED);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue