--- title: Edge scrolling created_at: 12/20/2025 updated_at: 12/29/2025 keywords: - scroll - edge - auto-scroll - EdgeScrollManager - drag status: published date: 12/20/2025 readability: 9 voice: 8 completeness: 9 accuracy: 9 notes: Could be more code-first in technical sections. Mention getIsEdgeScrolling() earlier for UI use cases. --- Edge scrolling pans the camera automatically when you drag shapes toward the viewport edges. This lets you move shapes across the canvas without releasing the drag to scroll manually. ## How it works Tool states that support edge scrolling call [EdgeScrollManager#updateEdgeScrolling](?) on every tick while the user is dragging. The manager reads the pointer position from the editor's inputs, works out how close it is to each viewport edge, and moves the camera. It does nothing while the camera is locked. The built-in select tool does this in its Translating (moving shapes), Brushing (selection box), and Resizing (dragging handles) states. The tool state, not the manager, decides when edge scrolling applies: the built-in states skip the call unless `editor.inputs.getIsDragging()` is true and `editor.inputs.getIsPanning()` is false. ## Tool integration To add edge scrolling to a custom tool, call `updateEdgeScrolling()` from the tick handler of the state where dragging happens, and only while the user is dragging: ```typescript import { StateNode, TLTickEventInfo } from 'tldraw' export class CustomDragState extends StateNode { static override id = 'dragging' override onTick({ elapsed }: TLTickEventInfo) { const { editor } = this if (!editor.inputs.getIsDragging() || editor.inputs.getIsPanning()) return editor.edgeScrollManager.updateEdgeScrolling(elapsed) } } ``` [EdgeScrollManager#getIsEdgeScrolling](?) returns true while the pointer is inside the edge zone, including during the start delay, and false once it leaves. Use it to show an indicator in your own UI. ## Configuration options Customize edge scrolling through [TldrawOptions](?). Set `edgeScrollSpeed` to `0` to turn it off entirely. | Option | Default | Description | | ------------------------ | ------- | ----------------------------------------------------------------------- | | `edgeScrollDelay` | 200 | Milliseconds the pointer must stay in the edge zone before scrolling | | `edgeScrollEaseDuration` | 200 | Milliseconds to ramp up to full speed after the delay | | `edgeScrollSpeed` | 25 | Base scroll speed in pixels per tick | | `edgeScrollDistance` | 8 | Width of the edge scroll zone in pixels | | `coarsePointerWidth` | 12 | Extra pointer width on each side for coarse (touch) pointers, in pixels | Set these options when creating the editor: ```tsx import { Tldraw } from 'tldraw' import 'tldraw/tldraw.css' const options = { edgeScrollSpeed: 50, // Double the default speed edgeScrollDelay: 100, // Start scrolling sooner } export default function App() { return (