frame method
void
frame({})
frame
Animates the viewport to fit all nodes within view, including zooming out if necessary.
Implementation
void frame({
double padding = 200.0,
Duration? animationDuration,
Curve curve = Curves.easeInOut,
}) {
if (nodes.isEmpty || viewController.viewportSize == null) return;
final viewportSize = viewController.viewportSize!;
// Compute the bounding box of all nodes
double minX = double.infinity;
double minY = double.infinity;
double maxX = double.negativeInfinity;
double maxY = double.negativeInfinity;
for (var node in nodes) {
final pos = node.position.toOffset();
if (pos.dx < minX) minX = pos.dx;
if (pos.dy < minY) minY = pos.dy;
if (pos.dx > maxX) maxX = pos.dx;
if (pos.dy > maxY) maxY = pos.dy;
}
final contentWidth = maxX - minX;
final contentHeight = maxY - minY;
// Compute scale to fit the bounding box into the viewport
final scaleX = (viewportSize.width - padding * 2) / contentWidth;
final scaleY = (viewportSize.height - padding * 2) / contentHeight;
final targetScale = scaleX < scaleY ? scaleX : scaleY;
// Clamp to min/max zoom
final clampedScale = targetScale.clamp(
viewController.mimZoomLevel,
viewController.maxZoomLevel,
);
// Compute center of the bounding box
final center = Offset(minX + contentWidth / 2, minY + contentHeight / 2);
// Compute the offset to center the bounding box
final newOffset =
-center * clampedScale +
Offset(viewportSize.width / 2, viewportSize.height / 2);
viewController.animateZoomAndPanTo(
targetOffset: newOffset,
targetZoom: clampedScale,
duration: animationDuration ?? const Duration(milliseconds: 400),
curve: curve,
);
}