diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index 3e5a8e040..5b9843ae1 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -336,6 +336,24 @@ RED.view = (function() { function init() { chart = $("#red-ui-workspace-chart"); + + // Add invisible spacer div to ensure scrollable area matches canvas dimensions + // At minimum zoom with "cover" behavior, SVG may be smaller than viewport in one dimension + // This spacer forces the browser to calculate scrollWidth/Height based on full canvas size + // Browser's maxScroll = scrollWidth - viewport will then correctly show canvas edges + var scrollSpacer = $('
') + .css({ + position: 'absolute', + top: 0, + left: 0, + width: space_width + 'px', + height: space_height + 'px', + pointerEvents: 'none', + visibility: 'hidden' + }) + .attr('id', 'red-ui-workspace-scroll-spacer') + .appendTo(chart); + chart.on('contextmenu', function(evt) { if (RED.view.DEBUG) { console.warn("contextmenu", { mouse_mode, event: d3.event }); @@ -2810,14 +2828,14 @@ RED.view = (function() { // Calculate the minimum zoom to ensure canvas always fills the viewport (no empty space) var viewportWidth = chart.width(); var viewportHeight = chart.height(); - + // Canvas is 8000x8000, calculate zoom to cover viewport var zoomToFitWidth = viewportWidth / space_width; var zoomToFitHeight = viewportHeight / space_height; - + // Use the LARGER zoom to ensure canvas covers entire viewport (no empty space visible) var calculatedMinZoom = Math.max(zoomToFitWidth, zoomToFitHeight); - + // Return the larger of the calculated min or the configured min // This ensures canvas always fills the viewport return Math.max(calculatedMinZoom, RED.view.zoomConstants.MIN_ZOOM); @@ -4969,6 +4987,15 @@ RED.view = (function() { eventLayer.attr("transform","scale("+scaleFactor+")"); outer.attr("width", space_width*scaleFactor).attr("height", space_height*scaleFactor); + // Update scroll spacer to match scaled canvas size + // This ensures scrollable area = canvas area + // Browser calculates maxScroll = scrollWidth - viewport, which correctly + // allows scrolling to see the far edges of canvas without going beyond + $('#red-ui-workspace-scroll-spacer').css({ + width: (space_width * scaleFactor) + 'px', + height: (space_height * scaleFactor) + 'px' + }); + // Don't bother redrawing nodes if we're drawing links if (showAllLinkPorts !== -1 || mouse_mode != RED.state.JOINING) {