# Archify viewBox Dimensions Calculation and Overflow Handling

> Discover how Archify calculates SVG viewBox dimensions and handles overflow with a four-stage pipeline. Learn about uniform scaling, bounds derivation, and CSS clip-path for seamless zooming.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: internals
- Published: 2026-09-13

---

**Archify calculates SVG viewBox dimensions through a four-stage pipeline in [`viewer/viewer-camera.js`](https://github.com/tt-a1i/archify/blob/main/viewer/viewer-camera.js) that computes uniform scaling, derives logical viewport bounds, and applies CSS clip-path to prevent overflow when zooming beyond native resolution.**

Archify is an open-source diagram rendering engine that navigates complex SVG structures through sophisticated camera logic. Understanding how Archify handles viewBox dimensions calculation and overflow is essential for developers customizing the viewer or debugging layout issues. The implementation centers on [`viewer/viewer-camera.js`](https://github.com/tt-a1i/archify/blob/main/viewer/viewer-camera.js), which transforms logical diagram coordinates into rendered pixels while enforcing strict boundary constraints to keep the visible area within the SVG's declared bounds.

## The Four-Stage viewBox Processing Pipeline

The [`viewer/viewer-camera.js`](https://github.com/tt-a1i/archify/blob/main/viewer/viewer-camera.js) module processes SVG viewBox coordinates through four distinct stages, transforming raw SVG attributes into bounded, user-navigable viewports.

### Stage 1: Extracting viewBox Coordinates

At line 19, the camera initializes by extracting the `SVGAnimatedRect` from the SVG element:

```javascript
var viewBox = svg.viewBox && svg.viewBox.baseVal;

```

This retrieval captures the `x`, `y`, `width`, and `height` attributes that define the logical coordinate system for all subsequent calculations. If the viewBox is invalid (for example, `width ≤ 0`), the functions return `null` immediately to prevent division-by-zero errors in scaling calculations.

### Stage 2: Computing Content Metrics

The `contentMetrics()` function (lines 31-40) derives the uniform transformation required to fit the viewBox inside the browser container. It calculates the **maximum uniform scale** by finding the minimum ratio between container dimensions and viewBox dimensions:

```javascript
Math.min(width / viewBox.width, height / viewBox.height)

```

This ensures the diagram maintains its aspect ratio without distortion. The function then computes **centering offsets** to handle letterboxing:

```javascript
offsetX = (width - viewBox.width * scale) / 2
offsetY = (height - viewBox.height * scale) / 2

```

These offsets center the diagram within the container when the aspect ratios differ, providing the foundation for all pan and zoom operations.

### Stage 3: Deriving the Logical Viewport

The `logicalViewport()` function (lines 44-66) maps the current pan and zoom state into viewBox coordinates. On narrow screens (`window.innerWidth ≤ 720`) displaying wide diagrams, it uses the container's scroll position instead of internal pan state to support horizontal scrolling.

The function enforces hard boundaries by clamping the viewport rectangle:

```javascript
// Minimum size enforcement and maximum bounds
Math.max(1, Math.min(viewBox.width, width))

// X coordinate clamping to viewBox edges
Math.max(viewBox.x, Math.min(viewBox.x + viewBox.width - width, x))

```

This logic prevents users from panning into empty space outside the diagram while maintaining a minimum viewport size of 1 logical unit.

### Stage 4: Clipping Visual Overflow

When users zoom beyond the natural resolution (`scale > 1.001`), the `clipToViewport()` function (lines 101-117) prevents rendering artifacts by applying a CSS `clip-path` property. This creates an `inset()` clip that hides any SVG content extending outside the current viewport boundaries.

The clip rectangle recalculates on every animation frame via `requestAnimationFrame` within the `syncViewportClip` loop until the camera motion settles (indicated by `cameraSettled`), ensuring smooth transitions during rapid zoom operations.

## Programmatic Viewport Control

Archify exposes the viewBox logic through a public API for building custom navigation controls:

```javascript
// Retrieve current logical viewport coordinates
const vp = Archify.view.logicalViewport();
console.log(vp);
// → { x: 120, y: 45, width: 800, height: 600, scale: 1.5 }

// Zoom uniformly while respecting viewBox limits
Archify.view.zoom(2.0);
Archify.view.centerAt(400, 300);

// Force clip recalculation after rapid programmatic changes
Archify.view.reveal(['node-123'], { instant: true });

```

## Related Viewer Architecture Files

While [`viewer/viewer-camera.js`](https://github.com/tt-a1i/archify/blob/main/viewer/viewer-camera.js) contains the core transformation logic, several adjacent modules consume these viewBox calculations:

- **viewer/semantic-radar.js**: Synchronizes the radar overview minimap using the same viewBox coordinate system
- **viewer/reader-layout.js**: Applies viewBox metrics to adjust responsive layouts during window resizing
- **viewer/export.js**: Preserves viewBox coordinates when generating exported SVG files

## Summary

- The viewBox pipeline in [`viewer/viewer-camera.js`](https://github.com/tt-a1i/archify/blob/main/viewer/viewer-camera.js) processes coordinates through four stages: extraction, metric calculation, viewport derivation, and overflow clipping
- `contentMetrics()` (lines 31-40) computes uniform scale and centering offsets to fit diagrams without distortion
- `logicalViewport()` (lines 44-66) clamps pan coordinates to prevent viewing areas outside the SVG viewBox boundaries
- CSS `clip-path` applied by `clipToViewport()` (lines 101-117) prevents visual overflow when zooming beyond native resolution
- The viewer supports both responsive scroll-based navigation on mobile and precise programmatic API control

## Frequently Asked Questions

### How does Archify prevent users from panning outside the diagram boundaries?

Archify enforces boundary constraints in the `logicalViewport()` function (lines 44-66) by clamping the viewport's x and y coordinates using `Math.max()` and `Math.min()` against the viewBox origin and dimensions. This ensures the visible region never exceeds the logical bounds defined by the SVG viewBox, preventing users from dragging empty space into view.

### What happens when the SVG lacks a valid viewBox attribute?

If `svg.viewBox.baseVal` returns null or contains invalid dimensions (where width or height is ≤ 0), the camera functions return `null` immediately at line 19 of [`viewer-camera.js`](https://github.com/tt-a1i/archify/blob/main/viewer-camera.js). This early exit prevents division-by-zero errors in subsequent scaling calculations and gracefully disables camera controls until a valid viewBox is present.

### Why does Archify use CSS clip-path instead of native SVG overflow handling?

Archify applies `clip-path` through `clipToViewport()` (lines 101-117) when the zoom scale exceeds 1.001 because it provides hardware-accelerated clipping that updates efficiently during `requestAnimationFrame` loops. This approach hides overflow content without modifying the SVG DOM structure or triggering expensive layout recalculations that would occur with viewBox attribute manipulation.

### How do I programmatically center the view on a specific node while respecting viewBox limits?

Use `Archify.view.centerAt(x, y)` followed by `Archify.view.zoom(level)`. These methods internally rely on `logicalViewport()`, which automatically clamps coordinates to valid viewBox ranges before rendering. This ensures the centered point remains visible even when targeting coordinates near the diagram edges.