apps/docs/content/sdk-features/eraser.mdx
The eraser tool deletes shapes from the canvas. Click a shape to erase it, or drag to erase every shape along the pointer's path. Users can select the eraser from the toolbar or press E; you can also activate it programmatically:
import { Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
export default function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw onMount={(editor) => editor.setCurrentTool('eraser')} />
</div>
)
}
A click erases the shapes under the pointer. Hold Cmd/Ctrl while clicking to erase only the topmost shape. A click that hits a shape inside a frame doesn't also erase the frame.
Dragging (or long-pressing) starts scribble erasing. A scribble trail follows the pointer, and every shape the path crosses is marked for deletion. Shapes aren't deleted until you release: marked shapes render at reduced opacity (32% of normal) so the user can see what's about to go.
Releasing the pointer deletes the marked shapes. Pressing Escape cancels the gesture and unmarks them.
The draw and highlight tools use the eraser too: hold Cmd/Ctrl and press down to erase without leaving the tool. They switch to eraser.pointing with onInteractionEnd set to their own id, and the eraser returns to that tool when the gesture ends.
Each erase gesture is a single history stopping point, so one undo brings back everything it deleted.
Locked shapes can't be erased. The eraser also skips shapes with a locked ancestor. See Locked shapes.
Groups are erased as a unit: hitting any shape inside a group marks the whole group. The exception is when the drag starts inside the group's bounds—then the eraser works on the shapes inside it and leaves the group alone.
Frames behave the same way. Start dragging inside a frame and the eraser deletes the frame's children without deleting the frame itself.
While a gesture is in progress, the editor tracks marked shapes in the current page state:
// Mark shapes as being erased (they render faded)
editor.setErasingShapes([shapeId1, shapeId2])
// Read the marked shapes
editor.getErasingShapeIds()
editor.getErasingShapes()
The eraser uses Editor#setErasingShapes, Editor#getErasingShapeIds, and Editor#getErasingShapes internally. You can use them from your own tools to get the same faded preview before deleting shapes with Editor#deleteShapes.
The eraser is an EraserTool with the id eraser and three child states. Tool lock doesn't apply to it. Pressing Escape in idle returns to the select tool.
| State | Description |
|---|---|
idle | Waiting for input. Pointer down transitions to pointing. |
pointing | The pointer is down. Shapes under the point are marked; releasing deletes them. Dragging transitions to erasing. |
erasing | Scribble erasing. Marks every shape the pointer path crosses; releasing deletes them. |
Hit testing during scribble erasing uses the segment between the previous and current pointer positions, with a margin of Editor#getHitTestMargin (hitTestMargin, or coarseHitTestMargin for touch, divided by the zoom level). This catches shapes even when the pointer moves quickly. Shapes clipped by a frame are skipped unless the pointer is inside the clip.