computeMinimapProjection function

MinimapProjection computeMinimapProjection({
  1. required Rect contentBounds,
  2. required Size mapSize,
  3. double padding = 8,
})

Builds the projection that fits contentBounds into a mapSize paint area, leaving padding pixels of margin on every side and centering the content.

Degenerate bounds (empty or non-finite) collapse to a centered unit box so the mapping stays finite.

Implementation

MinimapProjection computeMinimapProjection({
  required Rect contentBounds,
  required Size mapSize,
  double padding = 8,
}) {
  final availableW = mapSize.width - padding * 2;
  final availableH = mapSize.height - padding * 2;
  if (availableW <= 0 || availableH <= 0) {
    return const MinimapProjection(scale: 1, translation: Offset.zero);
  }

  var bounds = contentBounds;
  if (!bounds.isFinite || bounds.width <= 0 || bounds.height <= 0) {
    // Fall back to a 1x1 box centered on the (possibly finite) origin so a
    // single degenerate node still lands in the middle of the map.
    final center = bounds.isFinite ? bounds.center : Offset.zero;
    bounds = Rect.fromCenter(center: center, width: 1, height: 1);
  }

  final scale = (availableW / bounds.width) < (availableH / bounds.height)
      ? availableW / bounds.width
      : availableH / bounds.height;

  // Center the scaled content inside the map.
  final scaledW = bounds.width * scale;
  final scaledH = bounds.height * scale;
  final dx = padding + (availableW - scaledW) / 2 - bounds.left * scale;
  final dy = padding + (availableH - scaledH) / 2 - bounds.top * scale;
  return MinimapProjection(scale: scale, translation: Offset(dx, dy));
}