Skip to content

Commit c2c58cf

Browse files
crystianclaude
andcommitted
fix(ui): animate the explicit camera fits in the graph view
The re-arrange and fit buttons hard-snapped the camera via snapToVisibleFit() while the auto-fit (scan add / remove, curation re-fit) glided through runAnimatedFit(). That inconsistency made the explicit buttons jump instead of glide. Route both explicit fits through runAnimatedFit() so every camera fit in the view animates pan and zoom the same way, and drop the now-unused snapToVisibleFit(). computeVisibleFitTransform (the panel-width-aware fit math) is unchanged and still shared by every fit, so what gets framed is identical; only the explicit fits now animate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3427b77 commit c2c58cf

1 file changed

Lines changed: 10 additions & 21 deletions

File tree

ui/src/app/views/graph-view/graph-view.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,10 @@ export class GraphView implements OnInit {
845845
}
846846

847847
/**
848-
* Run the deferred animated fit. Pure signal tween via
848+
* Run the animated fit: the camera glides (pan + zoom) to frame the
849+
* on-screen nodes. Drives both the deferred auto-fit (scan add / remove,
850+
* curation re-fit) and the explicit re-arrange / fit buttons, so every
851+
* fit in the view animates the same way. Pure signal tween via
849852
* `viewport-animation`: the clamp lives inside `computeFitTransform`
850853
* (returns the scale already clamped to `[zoomMin, TAG_FIT_MAX_ZOOM]`),
851854
* so we get the camera-glide UX without Foblex's `FitToFlow`
@@ -879,8 +882,9 @@ export class GraphView implements OnInit {
879882
* Compute the pan/zoom that fits the on-screen nodes inside the
880883
* VISIBLE canvas, reserving the inspector panel's width when it is open
881884
* so the camera frames the area the operator actually sees (left of
882-
* the panel). Shared by the animated auto-fit and the snap-fit
883-
* (re-arrange / fit button) so both honour the panel identically.
885+
* the panel). Shared by every camera fit (the auto-fit on scan, the
886+
* curation re-fit, and the explicit re-arrange / fit buttons) so they
887+
* all honour the panel identically.
884888
*
885889
* Reads EFFECTIVE positions the way `projectVisible` does: user-pinned
886890
* (`nodePositions`) wins over the dagre output, layout map as fallback,
@@ -911,21 +915,6 @@ export class GraphView implements OnInit {
911915
});
912916
}
913917

914-
/**
915-
* Snap (no tween) the camera to `computeVisibleFitTransform()`. Used by
916-
* the re-arrange / fit button instead of Foblex's panel-blind
917-
* `fitToScreen`, so the fit reserves the inspector panel width the same
918-
* way the animated auto-fit does. Bumps the auto-fit token so any
919-
* in-flight tween is cancelled before the snap lands.
920-
*/
921-
private snapToVisibleFit(): void {
922-
const transform = this.computeVisibleFitTransform();
923-
if (!transform) return;
924-
++this.autoFitAnimToken;
925-
this.viewportPosition.set(transform.position);
926-
this.viewportScale.set(transform.scale);
927-
}
928-
929918
/**
930919
* Pan the camera so a single node sits in the centre of the visible
931920
* canvas (left of the inspector panel), WITHOUT changing zoom. Driven
@@ -1007,7 +996,7 @@ export class GraphView implements OnInit {
1007996
}
1008997

1009998
fitToScreen(): void {
1010-
this.snapToVisibleFit();
999+
this.runAnimatedFit();
10111000
}
10121001

10131002
resetLayout(): void {
@@ -1050,11 +1039,11 @@ export class GraphView implements OnInit {
10501039
// current full-graph auto-layout, reseeds every node, and persists.
10511040
// That's the original delete → re-arrange → save loop.
10521041
this.nodePositions.set(new Map());
1053-
this.snapToVisibleFit();
1042+
this.runAnimatedFit();
10541043
return;
10551044
}
10561045
void this.relayoutVisibleSubset(visiblePaths)
1057-
.then(() => this.snapToVisibleFit())
1046+
.then(() => this.runAnimatedFit())
10581047
.catch(() => {
10591048
// Layout failure (e.g. dagre CJS interop missing in tests) must
10601049
// not crash the view; the previous positions stay.

0 commit comments

Comments
 (0)