mirror of https://github.com/node-red/node-red.git
Fix zoom button animation and improve performance
- Fixed viewport jump to 0,0 by preventing click event from being passed as focal point - Added smooth animation to zoom buttons and keyboard shortcuts (animatedZoomView) - Doubled zoom step from 0.1 to 0.2 for faster zooming - Optimized animation performance by only updating transforms during animation frames - Fixed undefined variable issue (vis/gridScale -> eventLayer/outer) - Full redraw only happens once at end of animation, eliminating jarring experiencepan-zoom
parent
324ca52516
commit
95b750060f
|
|
@ -7,7 +7,7 @@ RED.view.zoomConstants = {
|
|||
MAX_ZOOM: 2.0,
|
||||
|
||||
// Zoom step for keyboard/button controls
|
||||
ZOOM_STEP: 0.1,
|
||||
ZOOM_STEP: 0.2,
|
||||
|
||||
// Animation settings
|
||||
DEFAULT_ZOOM_DURATION: 125, // ms, faster animation
|
||||
|
|
|
|||
|
|
@ -763,11 +763,11 @@ RED.view = (function() {
|
|||
'</span>')
|
||||
})
|
||||
|
||||
$("#red-ui-view-zoom-out").on("click", zoomOut);
|
||||
$("#red-ui-view-zoom-out").on("click", function() { zoomOut(); });
|
||||
RED.popover.tooltip($("#red-ui-view-zoom-out"),RED._('actions.zoom-out'),'core:zoom-out');
|
||||
$("#red-ui-view-zoom-zero").on("click", zoomZero);
|
||||
RED.popover.tooltip($("#red-ui-view-zoom-zero"),RED._('actions.zoom-reset'),'core:zoom-reset');
|
||||
$("#red-ui-view-zoom-in").on("click", zoomIn);
|
||||
$("#red-ui-view-zoom-in").on("click", function() { zoomIn(); });
|
||||
RED.popover.tooltip($("#red-ui-view-zoom-in"),RED._('actions.zoom-in'),'core:zoom-in');
|
||||
$("#red-ui-view-zoom-fit").on("click", zoomToFitAll);
|
||||
RED.popover.tooltip($("#red-ui-view-zoom-fit"),RED._('actions.zoom-fit'),'core:zoom-fit');
|
||||
|
|
@ -2847,16 +2847,16 @@ RED.view = (function() {
|
|||
|
||||
function zoomIn(focalPoint) {
|
||||
if (scaleFactor < RED.view.zoomConstants.MAX_ZOOM) {
|
||||
zoomView(scaleFactor + RED.view.zoomConstants.ZOOM_STEP, focalPoint);
|
||||
animatedZoomView(scaleFactor + RED.view.zoomConstants.ZOOM_STEP, focalPoint);
|
||||
}
|
||||
}
|
||||
function zoomOut(focalPoint) {
|
||||
var minZoom = calculateMinZoom();
|
||||
if (scaleFactor > minZoom) {
|
||||
zoomView(Math.max(scaleFactor - RED.view.zoomConstants.ZOOM_STEP, minZoom), focalPoint);
|
||||
animatedZoomView(Math.max(scaleFactor - RED.view.zoomConstants.ZOOM_STEP, minZoom), focalPoint);
|
||||
}
|
||||
}
|
||||
function zoomZero() { zoomView(1); }
|
||||
function zoomZero() { animatedZoomView(1); }
|
||||
|
||||
function zoomToFitAll() {
|
||||
// Get all nodes in active workspace
|
||||
|
|
@ -2931,9 +2931,11 @@ RED.view = (function() {
|
|||
|
||||
|
||||
function zoomView(factor, focalPoint) {
|
||||
console.log('=== ZOOM VIEW CALLED ===', 'factor:', factor, 'focalPoint:', focalPoint);
|
||||
// Early return if scale factor isn't actually changing
|
||||
// This prevents focal point shifts when at zoom limits
|
||||
if (Math.abs(scaleFactor - factor) < 0.001) {
|
||||
console.log('Zoom view SKIPPED - already at target zoom');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2960,8 +2962,10 @@ RED.view = (function() {
|
|||
chart.scrollTop(center[1] * scaleFactor - focalPoint[1]);
|
||||
} else {
|
||||
// Keep viewport center on the same workspace coordinates
|
||||
chart.scrollLeft(center[0] * scaleFactor - screenSize[0]/2);
|
||||
chart.scrollTop(center[1] * scaleFactor - screenSize[1]/2);
|
||||
var newScrollLeft = center[0] * scaleFactor - screenSize[0]/2;
|
||||
var newScrollTop = center[1] * scaleFactor - screenSize[1]/2;
|
||||
chart.scrollLeft(newScrollLeft);
|
||||
chart.scrollTop(newScrollTop);
|
||||
}
|
||||
|
||||
RED.view.navigator.resize();
|
||||
|
|
@ -3041,13 +3045,18 @@ RED.view = (function() {
|
|||
chart.scrollLeft(newScrollPos[0]);
|
||||
chart.scrollTop(newScrollPos[1]);
|
||||
|
||||
// During animation, only update the scale transform, not the full redraw
|
||||
// This is much more performant with many nodes
|
||||
eventLayer.attr("transform", "scale(" + scaleFactor + ")");
|
||||
outer.attr("width", space_width * scaleFactor).attr("height", space_height * scaleFactor);
|
||||
RED.view.navigator.resize();
|
||||
redraw();
|
||||
},
|
||||
onEnd: function() {
|
||||
cancelInProgressAnimation = null;
|
||||
// Ensure scaleFactor is exactly the target to prevent precision issues
|
||||
scaleFactor = targetFactor;
|
||||
// Full redraw at the end to ensure everything is correct
|
||||
redraw();
|
||||
if (RED.settings.get("editor.view.view-store-zoom")) {
|
||||
RED.settings.setLocal('zoom-level', targetFactor.toFixed(1));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue