# Understanding the Coordinate System for Zoom Focus Points in OpenScreen

> Learn the 0-1 coordinate system for OpenScreen zoom focus points. Discover how values are clamped within safe margins to prevent out-of-bounds viewing.

- Repository: [Sid/openscreen](https://github.com/siddharthvaddem/openscreen)
- Tags: deep-dive
- Published: 2026-04-03

---

**OpenScreen utilizes a normalized 0–1 coordinate system for zoom focus points where (0,0) represents the top-left corner and (1,1) the bottom-right, clamping values to safe margins based on zoom depth to prevent viewing outside video bounds.**

The open-source video editor OpenScreen (siddharthvaddem/openscreen) implements a resolution-independent approach to pan-and-zoom functionality through a normalized coordinate system for focus points. This design ensures that zoom focus points remain valid regardless of video resolution or UI stage size, with robust clamping mechanisms to keep the visible viewport within content boundaries.

## Normalized Coordinate System for Zoom Focus Points

OpenScreen defines a **zoom focus point** using the `ZoomFocus` interface, which employs normalized coordinates rather than pixel values.

### The ZoomFocus Interface

In [`src/components/video-editor/types.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/components/video-editor/types.ts), the interface is defined as:

```typescript
interface ZoomFocus {
  cx: number; // normalized horizontal center (0-1)
  cy: number; // normalized vertical center (0-1)
}

```

The `cx` and `cy` values represent fractions of the underlying video or stage dimensions. A value of `0` corresponds to the extreme left or top edge, while `1` represents the extreme right or bottom edge. The center of the frame sits at `(0.5, 0.5)`. Because these values are normalized, the same focus coordinates work consistently across different video resolutions and display sizes without requiring recalculation.

## Why Clamping Is Required

When users zoom in, the visible window becomes smaller relative to the content. If the focus point were allowed to sit arbitrarily close to the edge, portions of the viewport would fall outside the video bounds, producing blank areas or black bars. To prevent this visualization error, OpenScreen **clamps** the focus point based on the current **zoom depth** (a discrete level from 1 to 6) and its associated scale multiplier.

## How OpenScreen Clamps Zoom Focus Points

The clamping system operates through a pipeline of margin calculations and boundary enforcement functions located in [`src/components/video-editor/videoPlayback/focusUtils.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/components/video-editor/videoPlayback/focusUtils.ts).

### Depth-Based Scale Mapping

Each `ZoomDepth` level maps to a specific multiplier stored in the `ZOOM_DEPTH_SCALES` array, defined in [`src/components/video-editor/types.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/components/video-editor/types.ts) (lines 56-63). These scales determine how aggressively the viewport magnifies the content, which directly affects how much margin must be preserved at the edges.

### Margin Calculation with getFocusBoundsForScale

For any given scale, the allowed focus region shrinks by a margin calculated as `1 / (2 × scale)` on every side. The `getFocusBoundsForScale` function (lines 42-51 in [`focusUtils.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/focusUtils.ts)) implements this logic, returning the valid minimum and maximum bounds for both `cx` and `cy` at the specified zoom level.

### Stage-Level and Scale-Level Clamping

OpenScreen provides two primary clamping functions:

- **`clampFocusToStage`** (lines 54-66): First constrains raw focus values to the generic `[0, 1]` range, then applies depth-specific bounds from `getFocusBoundsForScale` to ensure the focus stays within safe margins for the current zoom depth.

- **`clampFocusToScale`** (lines 68-78): Performs the same boundary enforcement using a raw numeric `zoomScale` rather than a discrete depth level, useful for temporary zoom values during animations or pinch-to-zoom gestures.

### Soft Clamping for Smooth UX

To prevent jarring snaps when users drag near boundaries, `softenFocusToScale` (lines 81-96 in [`focusUtils.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/focusUtils.ts)) implements **soft clamping**. This function applies gentle easing near the margins, allowing the focus point to slide smoothly rather than hitting hard stops at the edge.

All clamping functions rely on a utility `clamp` function (lines 74-77 in [`types.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/types.ts)) that safely handles `NaN` values and out-of-range inputs.

## Implementation Examples

### Clamping a Focus Point to Current Zoom Depth

When processing user input from drag operations, clamp the raw coordinates to safe bounds:

```typescript
import {
  clampFocusToStage,
} from '@/components/video-editor/videoPlayback/focusUtils';
import { DEFAULT_ZOOM_DEPTH } from '@/components/video-editor/types';

const rawFocus = { cx: 0.95, cy: 0.03 }; // User dragged near corner

// Clamp based on current depth (e.g., depth = 3)
const safeFocus = clampFocusToStage(rawFocus, 3, { width: 1280, height: 720 });
console.log(safeFocus); // => { cx: 0.78, cy: 0.22 } (example values)

```

### Using Custom Zoom Scales

For non-discrete zoom animations, use `clampFocusToScale`:

```typescript
const customScale = 2.4; // During pinch-zoom animation
const clamped = clampFocusToScale(rawFocus, customScale);
// Returns focus constrained to safe margins for scale 2.4

```

### Converting Stage Coordinates to Video Space

Transform normalized focus points to actual video pixel coordinates:

```typescript
import { stageFocusToVideoSpace } from '@/components/video-editor/videoPlayback/focusUtils';

const stageSize = { width: 800, height: 600 };
const videoSize = { width: 1920, height: 1080 };
const baseScale = 1.5;
const baseOffset = { x: 100, y: 50 };

const videoSpaceFocus = stageFocusToVideoSpace(
  rawFocus,
  stageSize,
  videoSize,
  baseScale,
  baseOffset,
);
// Conversion logic resides in focusUtils.ts lines 98-124

```

## Summary

- OpenScreen employs a **normalized 0–1 coordinate system** for zoom focus points defined in [`src/components/video-editor/types.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/components/video-editor/types.ts), enabling resolution-independent focus positioning.
- The **clamping mechanism** prevents viewport bleed by calculating safe margins based on the current zoom scale using `getFocusBoundsForScale`.
- **`clampFocusToStage`** enforces boundaries for discrete zoom depths, while **`clampFocusToScale`** handles arbitrary numeric scales for animations.
- **Soft clamping** via `softenFocusToScale` provides smooth UX by easing focus movements near boundaries rather than applying hard cuts.
- All boundary calculations reside in [`src/components/video-editor/videoPlayback/focusUtils.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/components/video-editor/videoPlayback/focusUtils.ts), with type definitions and utility functions in [`types.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/types.ts).

## Frequently Asked Questions

### What is the valid range for zoom focus point coordinates in OpenScreen?

Zoom focus points use normalized coordinates where both `cx` (horizontal) and `cy` (vertical) range from **0 to 1**, inclusive. A value of `0` represents the left or top edge, `1` represents the right or bottom edge, and `0.5` represents the exact center of the video or stage. These normalized values allow the same focus coordinates to work across different video resolutions without modification.

### How does OpenScreen prevent the zoom viewport from showing areas outside the video?

OpenScreen calculates safe margins based on the current zoom scale using the formula `1 / (2 × scale)` and clamps focus points within these bounds. The `clampFocusToStage` function in [`focusUtils.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/focusUtils.ts) first ensures values stay within `[0, 1]`, then applies depth-specific constraints to guarantee the zoomed viewport never extends beyond the video edges, eliminating blank spaces or black bars.

### What is the difference between clampFocusToStage and clampFocusToScale?

**`clampFocusToStage`** accepts a discrete `ZoomDepth` level (1–6) and uses the predefined scale mappings in `ZOOM_DEPTH_SCALES` to determine clamping boundaries. **`clampFocusToScale`** accepts a raw numeric `zoomScale` directly, making it suitable for temporary zoom values during pinch gestures or smooth zoom animations where the scale doesn't correspond to a discrete depth level. Both functions ultimately rely on `getFocusBoundsForScale` to calculate safe margins.

### Why does OpenScreen implement soft clamping for zoom focus points?

Soft clamping via `softenFocusToScale` applies mathematical easing near the boundaries rather than hard truncation, preventing jarring visual snaps when users drag the focus point toward the edges of the frame. This creates a smoother user experience by allowing the focus to glide gently toward its limit instead of stopping abruptly, while still ensuring the viewport remains within valid video bounds.