From 86e82873bb1f537e86526e362f4a535424c2c08a Mon Sep 17 00:00:00 2001 From: Philipp Scheede Date: Thu, 20 Mar 2025 21:25:23 +0100 Subject: [PATCH] Improve zoom and scroll Zooming is now exponential. Scrolling now follows the mouse directly. Zooming was linear before, which meant that the first zoom step was perceived to be much bigger than the last. With exponential zooming, each step now feels the same. Zooming with mouse was too sensitive, in my opinion. Therefore I halved the zoom factor with the mouse. --- src/js/structurizr-diagram.js | 24 +++++++++++++----------- src/static.html | 6 +++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/js/structurizr-diagram.js b/src/js/structurizr-diagram.js index 36f446f..367119e 100644 --- a/src/js/structurizr-diagram.js +++ b/src/js/structurizr-diagram.js @@ -33,7 +33,7 @@ structurizr.ui.Diagram = function(id, diagramIsEditable, constructionCompleteCal const DEFAULT_MAX_ZOOM_SCALE = 2; var maxZoomScale = DEFAULT_MAX_ZOOM_SCALE; const zoomSteps = 40; - var zoomDelta = (maxZoomScale - minZoomScale) / zoomSteps; + var zoomFactor = Math.pow(maxZoomScale / minZoomScale, 1 / zoomSteps); var pageSizeDelta = 100; const thumbnailWidth = 400; @@ -577,7 +577,7 @@ structurizr.ui.Diagram = function(id, diagramIsEditable, constructionCompleteCal if (embedded) { self.zoomFitWidth(); minZoomScale = scale; - zoomDelta = (maxZoomScale - minZoomScale) / zoomSteps; + zoomFactor = Math.pow(maxZoomScale / minZoomScale, 1 / zoomSteps); } else { self.zoomToWidthOrHeight(); } @@ -972,7 +972,7 @@ structurizr.ui.Diagram = function(id, diagramIsEditable, constructionCompleteCal if (embedded) { self.zoomFitWidth(); minZoomScale = scale; - zoomDelta = (maxZoomScale - minZoomScale) / zoomSteps; + zoomFactor = Math.pow(maxZoomScale / minZoomScale, 1 / zoomSteps); } else { maxZoomScale = DEFAULT_MAX_ZOOM_SCALE; self.zoomToWidthOrHeight(); @@ -1632,7 +1632,7 @@ structurizr.ui.Diagram = function(id, diagramIsEditable, constructionCompleteCal function setZoomAndMargins() { minZoomScale = scale; maxZoomScale = DEFAULT_MAX_ZOOM_SCALE; - zoomDelta = (maxZoomScale - minZoomScale) / zoomSteps; + zoomFactor = Math.pow(maxZoomScale / minZoomScale, 1 / zoomSteps); var minimumWidth = minZoomScale * diagramWidth; var minimumHeight = minZoomScale * diagramHeight; @@ -3915,12 +3915,14 @@ structurizr.ui.Diagram = function(id, diagramIsEditable, constructionCompleteCal this.scrollToPoint(centreX, centreY, clientTarget.x, clientTarget.y); }; - this.zoomIn = function(evt) { - zoomToAndScroll(Math.min(scale + zoomDelta, maxZoomScale), evt); + this.zoomIn = function(evt, slow) { + const speedFactor = slow ? 0.5 : 1; + zoomToAndScroll(Math.min(scale * (zoomFactor ** speedFactor), maxZoomScale), evt); }; - this.zoomOut = function(evt) { - zoomToAndScroll(Math.max(scale - zoomDelta, minZoomScale), evt); + this.zoomOut = function(evt, slow) { + const speedFactor = slow ? 0.5 : 1; + zoomToAndScroll(Math.max(scale / (zoomFactor ** speedFactor), minZoomScale), evt); }; function zoomToAndScroll(zoomScale, evt) { @@ -5872,8 +5874,8 @@ structurizr.ui.Diagram = function(id, diagramIsEditable, constructionCompleteCal var deltaX = (dragStartPosition.x - x); var deltaY = (dragStartPosition.y - y); - viewport.scrollLeft(scrollStartPosition.x + (deltaX * scale)); - viewport.scrollTop(scrollStartPosition.y + (deltaY * scale)); + viewport.scrollLeft(scrollStartPosition.x + (deltaX)); + viewport.scrollTop(scrollStartPosition.y + (deltaY)); } } @@ -7240,4 +7242,4 @@ structurizr.ui.PaperSizes = function() { return definitions[paperSize]; }; -}; \ No newline at end of file +}; diff --git a/src/static.html b/src/static.html index 05861a2..08f7176 100644 --- a/src/static.html +++ b/src/static.html @@ -218,9 +218,9 @@ document.getElementById('diagram-viewport').addEventListener('wheel', function (event) { if (event.ctrlKey === true) { if (event.wheelDelta > 0) { - structurizr.diagram.zoomIn(event); + structurizr.diagram.zoomIn(event, true); } else { - structurizr.diagram.zoomOut(event); + structurizr.diagram.zoomOut(event, true); } event.preventDefault(); @@ -448,4 +448,4 @@ structurizr.diagram.setKeyboardShortcutsEnabled(true); }); } - \ No newline at end of file +