@@ -2197,6 +2197,12 @@ function NodeCanvas() {
21972197
21982198
21992199 // Edge Panning Effect
2200+ // Ref to hold the latest performDragUpdate function to avoid restarting the pan loop
2201+ const performDragUpdateRef = useRef(performDragUpdate);
2202+ useEffect(() => {
2203+ performDragUpdateRef.current = performDragUpdate;
2204+ }, [performDragUpdate]);
2205+
22002206 useEffect(() => {
22012207 if (!draggingNodeInfo) return;
22022208
@@ -2213,36 +2219,41 @@ function NodeCanvas() {
22132219
22142220 const { x: mouseX, y: mouseY } = mousePositionRef.current;
22152221 const bounds = viewportBoundsRef.current;
2216- const margin = 150; // Larger edge zone for better responsiveness
2217- const maxSpeed = 25; // Faster max speed
2222+ // TUNED SENSITIVITY:
2223+ // Reduced margin from 150 to 75 for less aggressive activation
2224+ const margin = 75;
2225+ // Reduced maxSpeed from 25 to 15 for more control
2226+ const maxSpeed = 15;
22182227
22192228 let dx = 0;
22202229 let dy = 0;
22212230
2231+ // Used power 1.5 instead of 2 for a slightly more linear response curve
2232+
22222233 // Left
22232234 if (mouseX < bounds.x + margin) {
22242235 const dist = (bounds.x + margin) - mouseX;
22252236 const ratio = Math.min(1, dist / margin); // Cap at 1 (max speed)
2226- dx = -maxSpeed * Math.pow(ratio, 2 );
2237+ dx = -maxSpeed * Math.pow(ratio, 1.5 );
22272238 }
22282239 // Right
22292240 else if (mouseX > bounds.x + bounds.width - margin) {
22302241 const dist = mouseX - (bounds.x + bounds.width - margin);
22312242 const ratio = Math.min(1, dist / margin);
2232- dx = maxSpeed * Math.pow(ratio, 2 );
2243+ dx = maxSpeed * Math.pow(ratio, 1.5 );
22332244 }
22342245
22352246 // Top
22362247 if (mouseY < bounds.y + margin) {
22372248 const dist = (bounds.y + margin) - mouseY;
22382249 const ratio = Math.min(1, dist / margin);
2239- dy = -maxSpeed * Math.pow(ratio, 2 );
2250+ dy = -maxSpeed * Math.pow(ratio, 1.5 );
22402251 }
22412252 // Bottom
22422253 else if (mouseY > bounds.y + bounds.height - margin) {
22432254 const dist = mouseY - (bounds.y + bounds.height - margin);
22442255 const ratio = Math.min(1, dist / margin);
2245- dy = maxSpeed * Math.pow(ratio, 2 );
2256+ dy = maxSpeed * Math.pow(ratio, 1.5 );
22462257 }
22472258
22482259 if (dx !== 0 || dy !== 0) {
@@ -2278,7 +2289,8 @@ function NodeCanvas() {
22782289 setPanOffset(newPan);
22792290
22802291 // Force update node position with new pan to keep it under mouse
2281- performDragUpdate(mouseX, mouseY, newPan, currentZoom, draggingNodeInfoRef.current);
2292+ // Use the REF version of performDragUpdate to avoid dependency on the changed callback
2293+ performDragUpdateRef.current(mouseX, mouseY, newPan, currentZoom, draggingNodeInfoRef.current);
22822294 }
22832295 } else {
22842296 // Not in edge zone - allow handleMouseMove RAF to update node position
@@ -2290,7 +2302,7 @@ function NodeCanvas() {
22902302
22912303 animationFrameId = requestAnimationFrame(panLoop);
22922304 return () => cancelAnimationFrame(animationFrameId);
2293- }, [draggingNodeInfo, performDragUpdate ]);
2305+ }, [draggingNodeInfo]); // Removed performDragUpdate from dependencies to prevent loop restart on every frame
22942306
22952307 const stopPanMomentum = useCallback(() => {
22962308 const { animationId } = panMomentumRef.current;
0 commit comments