@@ -24,18 +24,26 @@ document.addEventListener("DOMContentLoaded", () => {
2424 const zoomOutBtn = controls . querySelector ( ".zoom-out" ) ;
2525 if ( ! ( zoomInBtn instanceof HTMLButtonElement ) || ! ( zoomOutBtn instanceof HTMLButtonElement ) ) return ;
2626
27- // Lock the viewport height to the SVG's natural rendered height
28- viewport . style . height = `${ svg . getBoundingClientRect ( ) . height } px` ;
27+ // Lock the viewport height to the SVG's natural rendered height (ignoring any zoom transform)
28+ const updateViewportHeight = ( ) => {
29+ const prevTransform = svg . style . transform ;
30+ svg . style . transform = "" ;
31+ viewport . style . height = `${ svg . getBoundingClientRect ( ) . height } px` ;
32+ svg . style . transform = prevTransform ;
33+ } ;
34+ updateViewportHeight ( ) ;
35+ window . addEventListener ( "resize" , updateViewportHeight ) ;
2936
3037 const MIN_SCALE = 1 ;
31- const MAX_SCALE = 2.5 ;
38+ const MAX_SCALE = 4 ;
3239 const ZOOM_STEP = 0.15 ;
3340 const BUTTON_ZOOM_STEP = 0.5 ;
3441 const ANIMATION_DURATION = 200 ;
3542
3643 let scale = MIN_SCALE ;
3744 let panX = 0 ;
3845 let panY = 0 ;
46+ let animationFrameId = 0 ;
3947 let isDragging = false ;
4048 let dragStartX = 0 ;
4149 let dragStartY = 0 ;
@@ -92,6 +100,8 @@ document.addEventListener("DOMContentLoaded", () => {
92100 }
93101
94102 function animateZoomAt ( /** @type {number } */ clientX , /** @type {number } */ clientY , /** @type {number } */ newTargetScale ) {
103+ cancelAnimationFrame ( animationFrameId ) ;
104+
95105 const targetScale = Math . min ( MAX_SCALE , Math . max ( MIN_SCALE , newTargetScale ) ) ;
96106 const startScale = scale ;
97107 const startPanX = panX ;
@@ -107,16 +117,16 @@ document.addEventListener("DOMContentLoaded", () => {
107117 const targetPanY = pointY - contentY * targetScale ;
108118
109119 const startTime = performance . now ( ) ;
110- function step ( /** @type {number } */ now ) {
120+ const step = ( /** @type {number } */ now ) => {
111121 const t = Math . min ( 1 , ( now - startTime ) / ANIMATION_DURATION ) ;
112122 const ease = t * ( 2 - t ) ; // ease-out quadratic
113123 scale = startScale + ( targetScale - startScale ) * ease ;
114124 panX = startPanX + ( targetPanX - startPanX ) * ease ;
115125 panY = startPanY + ( targetPanY - startPanY ) * ease ;
116126 applyTransform ( ) ;
117- if ( t < 1 ) requestAnimationFrame ( step ) ;
118- }
119- requestAnimationFrame ( step ) ;
127+ if ( t < 1 ) animationFrameId = requestAnimationFrame ( step ) ;
128+ } ;
129+ animationFrameId = requestAnimationFrame ( step ) ;
120130 }
121131
122132 // Scroll wheel zoom
0 commit comments