[]previous and next page

Tools

How the built-in tools work, how to switch between them, and how input from mouse, touch and pen reaches them.

A tool turns input into edits. The select tool turns a drag into a move, the rectangle tool turns a drag into a new shape, the eraser turns a swipe into deletions. You switch tools with the toolbar, the keyboard or code:

ts
editor.setTool('rectangle')
editor.state.toolId // 'rectangle'
editor.toggleToolLock() // keep the tool after creating a shape (Q)

The built-in tools#

Id Key What it does
select V 1 Select, move, resize, rotate, edit points and text
hand H Pan. Holding Space does the same with any tool
rectangle, ellipse, diamond and other geo kinds R O D Drag to size, click for a default size
arrow, line A L Drag for two points, click to place many (Lines and arrows)
draw P Freehand, with pen pressure. ⇧ draws a straight segment from the last stroke
highlight ⇧ D A translucent highlighter
text T Click for auto-width text, drag for a fixed width
note N A sticky note, ready to type
frame F A frame that owns what's inside it
eraser E Erase what you swipe across. Shapes fade first; Esc mid-swipe cancels the erase
laser K A fading pointer for presenting, shared with collaborators

Every shortcut is listed on the Keyboard shortcuts page, generated from the engine itself.

The select tool#

The select tool is the one people spend their time in, so it does a lot quietly:

  • Click selects, Shift-click adds or removes, drag on empty canvas draws a marquee (hold Alt for a lasso).
  • Drag moves, snapping to edges, centers, equal gaps and the grid. Hold Alt to duplicate while dragging, ⇧ to lock to an axis.
  • Handles resize from any side or corner. ⇧ keeps the aspect ratio, Alt resizes from the center.
  • Rotate from the handle above the selection or just outside a corner. ⇧ snaps to 15°.
  • Double-click edits text, enters a group, or edits a line's points.
  • Esc peels one layer at a time: finish editing, leave the group, clear the selection.

Input from anything#

The host turns mouse, touch, pen, trackpad and keyboard input into one stream of events, so tools never have to care where input came from:

  • Mouse and trackpad. The wheel pans on a trackpad and zooms with a mouse (configurable with wheelBehavior). Pinch zooms.
  • Touch. Two fingers pan and pinch; a long press opens the context menu. Hit areas and handles grow for fingers.
  • Pen. Pressure flows into freehand strokes. In pen mode, fingers pan while the pen draws, so a resting palm never leaves marks.
  • Keyboard. Arrow keys nudge (with ⇧ for bigger steps), Tab walks through shapes, and every command has a shortcut.

Tools are state machines#

Each tool is a small tree of states. The select tool, for instance, moves between idle, pointing_shape, translating, resizing, rotating, dragging_handle and editing_shape. You can see where it is at any time:

ts
editor.state.toolPath // 'select.translating'
editor.isIn('select.resizing') // false
editor.on('tool', ({ id, path }) => console.log(id, path))

This structure is what makes gestures cancel cleanly: every state knows how to undo what it started. It's also how you write your own tool: see Custom tools.