--- title: Coordinates created_at: 12/20/2025 updated_at: 12/29/2025 keywords: - coordinates - screen - page - viewport - transform reviewed_by: steveruizok status: published date: 12/20/2025 readability: 9 voice: 8 completeness: 9 accuracy: 9 notes: Could use more questions-as-transitions per voice guide. Consider adding visual diagram and API reference links. --- The editor uses three coordinate systems: screen space, viewport space, and page space. When you move the mouse over the canvas, the browser gives you screen coordinates. To create a shape at that location, you need to convert those coordinates to page space. The editor provides methods to convert between these coordinate systems. You'll use these when building custom tools, positioning DOM overlays, or responding to pointer events. The [Camera](/sdk-features/camera) article explains the camera values these conversions depend on. | Method | Description | | -------------------------- | ------------------------------------------------------------------- | | [Editor#screenToPage](?) | Convert a screen point to page space. | | [Editor#pageToScreen](?) | Convert a page point to screen space. | | [Editor#pageToViewport](?) | Convert a page point to viewport space (relative to the container). | ## The three coordinate systems ### Screen space Screen space uses pixel coordinates from the browser window's top-left corner. These are the values you get from `MouseEvent.clientX` and `MouseEvent.clientY`. Screen coordinates include any space outside the editor container, like browser chrome or other page content. ### Viewport space Viewport space uses pixel coordinates from the editor container's top-left corner. This accounts for where the editor sits on the page. If the editor is embedded in a scrollable element or positioned away from the browser's origin, viewport coordinates differ from screen coordinates by that offset. The editor tracks the container's position in [Editor#getViewportScreenBounds](?). ### Page space Page space is the infinite canvas itself. A shape at `x: 100, y: 200` stays at those coordinates regardless of how the user pans or zooms. Top-level shapes store their position in page space; children of frames and groups store it relative to their parent. See [Parenting](/sdk-features/parenting) for the helpers that convert between shape space and page space. The camera determines which part of page space is visible. When you zoom in, the same page-space region takes up more screen pixels. When you pan, different page-space coordinates come into view. ## Coordinate transformations ### Screen to page space Use [Editor#screenToPage](?) to convert screen coordinates to page coordinates. This is the most common transformation. It accounts for the editor container's position, the camera position, and the zoom level: ```typescript // Convert mouse event coordinates to page space const pagePoint = editor.screenToPage({ x: event.clientX, y: event.clientY }) // Create a shape at the clicked location editor.createShape({ type: 'geo', x: pagePoint.x, y: pagePoint.y, props: { w: 100, h: 100, geo: 'rectangle' }, }) ``` ### Page to screen space Use [Editor#pageToScreen](?) to convert page coordinates to screen coordinates, for example to position a DOM element that lives outside the editor container: ```typescript // Convert shape position to screen coordinates const shape = editor.getShape(shapeId) if (!shape) return const screenPoint = editor.pageToScreen({ x: shape.x, y: shape.y }) // Position a DOM element at the shape's screen location element.style.left = `${screenPoint.x}px` element.style.top = `${screenPoint.y}px` ``` ### Page to viewport space Use [Editor#pageToViewport](?) to convert page coordinates to viewport coordinates. This is `pageToScreen()` without the container offset, so use it for canvas rendering or for positioning elements inside the editor container: ```typescript // Get viewport coordinates for a page point const viewportPoint = editor.pageToViewport({ x: 500, y: 300 }) // Check if a point is visible in the viewport const viewportBounds = editor.getViewportScreenBounds() const isVisible = viewportPoint.x >= 0 && viewportPoint.x <= viewportBounds.w && viewportPoint.y >= 0 && viewportPoint.y <= viewportBounds.h ``` ## Viewport bounds Use [Editor#getViewportScreenBounds](?) to get the editor container's position and size in screen space: ```typescript const screenBounds = editor.getViewportScreenBounds() // screenBounds.x, screenBounds.y - container position in screen space // screenBounds.w, screenBounds.h - container dimensions in pixels ``` Use [Editor#getViewportPageBounds](?) to get the visible area in page space: ```typescript const pageBounds = editor.getViewportPageBounds() // pageBounds.x, pageBounds.y - top-left corner of visible area in page space // pageBounds.w, pageBounds.h - visible area dimensions in page units ``` Both are reactive, so you can read them inside `track` components or `useValue` and re-render when the user pans or zooms. At higher zoom levels, the visible page-space area is smaller. ## Using the inputs manager The editor's inputs manager tracks the current pointer position, so you can read it from anywhere in your code: ```typescript // Get the current pointer position const screenPoint = editor.inputs.getCurrentScreenPoint() const pagePoint = editor.inputs.getCurrentPagePoint() // Get the position where the current drag started const originScreenPoint = editor.inputs.getOriginScreenPoint() const originPagePoint = editor.inputs.getOriginPagePoint() ``` Despite the name, the inputs manager's "screen point" is relative to the editor container, which this article calls viewport space. Don't pass it to `screenToPage()` and don't subtract `getViewportScreenBounds()` from it. Pointer event info is different: its `point` property holds `clientX`/`clientY`, so it is in screen space and converts with `screenToPage()`: ```typescript editor.on('event', (event) => { if (event.type === 'pointer' && event.name === 'pointer_down') { const pagePoint = editor.screenToPage(event.point) // Use pagePoint for shape manipulation } }) ``` ## Related examples - [Reactive inputs](/examples/editor-api/reactive-inputs) - Display page and screen coordinates reactively as the pointer moves. - [Selection UI](/examples/ui/selection-ui) - Use selection bounds in screen space to position custom UI around shapes.