Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tldraw/tldraw/llms.txt

Use this file to discover all available pages before exploring further.

ZoomTool

The ZoomTool provides an interactive way to zoom in and out of the canvas by clicking or drawing a selection rectangle. It’s typically activated temporarily and returns to the previous tool after the zoom operation completes.

Overview

The ZoomTool enables:
  • Click to zoom in at a point
  • Alt/Option + Click to zoom out at a point
  • Drag to draw a zoom rectangle (zoom to fit that region)
  • Automatic return to the previous tool after zooming
  • Visual feedback with zoom-in/zoom-out cursors

Static Properties

id
string
default:"'zoom'"
The tool identifier
initial
string
default:"'idle'"
Initial child state when the tool is activated
isLockable
boolean
default:"false"
The zoom tool cannot be locked

Child States

The ZoomTool has four child states:
  • Idle - Default state, waiting for user input
  • Pointing - User has pressed down but not yet started dragging
  • ZoomBrushing - User is drawing a rectangle to zoom to that region
  • ZoomQuick - Quick zoom mode for immediate zoom operations

Instance Properties

info
TLPointerEventInfo & { onInteractionEnd?: string }
Stores information about the interaction, including which tool to return to

Lifecycle Methods

onEnter()

Called when the zoom tool is activated.
onEnter(info: TLPointerEventInfo & { onInteractionEnd: string }): void
info
TLPointerEventInfo & { onInteractionEnd: string }
required
Event info including the tool ID to return to after zooming (e.g., ‘select.idle’)
Stores the interaction info, sets the tool ID mask (to show the previous tool in UI), and updates the cursor.

onExit()

Called when exiting the zoom tool.
onExit(): void
Clears the tool ID mask, resets the zoom brush state, and restores the default cursor.

Event Handlers

onKeyDown()

Updates the cursor when keys are pressed (e.g., Alt for zoom out).
onKeyDown(): void

onKeyUp()

Handles key release events.
onKeyUp(info: TLKeyboardEventInfo): void
info
TLKeyboardEventInfo
required
Keyboard event information
Updates the cursor and completes the zoom operation if the ‘Z’ key is released.

onInterrupt()

Handles interruptions to the zoom operation.
onInterrupt(): void
Completes the zoom operation and returns to the previous tool.

Usage Example

import { ZoomTool } from '@tldraw/tldraw'

// Activate the zoom tool temporarily
editor.setCurrentTool('zoom', { onInteractionEnd: 'select' })

// The tool will automatically return to 'select' after zooming

// Check if zoom tool is active
const isZoomActive = editor.getCurrentToolId() === 'zoom'

Programmatic Zooming

You typically don’t need the ZoomTool for programmatic zooming:
// Zoom in at a point
const point = { x: 100, y: 100 }
editor.zoomIn(point)

// Zoom out at a point
editor.zoomOut(point)

// Zoom to fit specific bounds
editor.zoomToBounds({
  x: 0,
  y: 0,
  w: 1000,
  h: 800
})

// Zoom to fit all content
editor.zoomToFit()

// Zoom to selection
editor.zoomToSelection()

// Set specific zoom level (1.0 = 100%)
editor.setZoomLevel(1.5)

// Get current zoom level
const zoom = editor.getZoomLevel()

Keyboard Shortcuts

By default in tldraw:
  • Z - Activate zoom tool (hold and click/drag)
  • Alt/Option + Z - Zoom out mode
  • Ctrl/Cmd + + - Zoom in
  • Ctrl/Cmd + - - Zoom out
  • Ctrl/Cmd + 0 - Reset to 100% zoom
  • Ctrl/Cmd + 1 - Zoom to fit
  • Ctrl/Cmd + 2 - Zoom to selection

Extending ZoomTool

You can extend the ZoomTool to customize its behavior:
import { ZoomTool, TLPointerEventInfo } from '@tldraw/tldraw'

class MyCustomZoomTool extends ZoomTool {
  override onEnter(info: TLPointerEventInfo & { onInteractionEnd: string }) {
    super.onEnter(info)
    console.log('Zoom tool activated')
  }
  
  override onExit() {
    super.onExit()
    console.log('Zoom tool deactivated')
  }
  
  // Customize cursor behavior
  private override updateCursor() {
    if (this.editor.inputs.getAltKey()) {
      this.editor.setCursor({ type: 'zoom-out', rotation: 0 })
    } else {
      this.editor.setCursor({ type: 'zoom-in', rotation: 0 })
    }
  }
}

Common Patterns

Temporary Zoom Tool Activation

// Hold 'Z' key to activate zoom tool
let previousTool: string

window.addEventListener('keydown', (e) => {
  if (e.code === 'KeyZ' && !e.repeat) {
    previousTool = editor.getCurrentToolId()
    editor.setCurrentTool('zoom', { 
      onInteractionEnd: previousTool 
    })
  }
})

window.addEventListener('keyup', (e) => {
  if (e.code === 'KeyZ') {
    editor.setCurrentTool(previousTool)
  }
})

Zoom to Selected Shapes

// Zoom to fit selected shapes with padding
function zoomToSelection(padding = 50) {
  const selectedShapes = editor.getSelectedShapes()
  
  if (selectedShapes.length === 0) {
    console.log('No shapes selected')
    return
  }
  
  const bounds = editor.getSelectionPageBounds()
  
  if (bounds) {
    editor.zoomToBounds({
      x: bounds.x - padding,
      y: bounds.y - padding,
      w: bounds.w + padding * 2,
      h: bounds.h + padding * 2
    }, {
      animation: { duration: 300, easing: EASINGS.easeInOutCubic }
    })
  }
}

Zoom with Constraints

// Limit zoom levels
const MIN_ZOOM = 0.1
const MAX_ZOOM = 5

const dispose = editor.sideEffects.registerBeforeChangeHandler(
  'camera',
  (prev, next) => {
    return {
      ...next,
      z: Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, next.z))
    }
  }
)

// Clean up when done
dispose()

Smooth Zoom Animation

import { EASINGS } from '@tldraw/editor'

// Zoom with custom animation
editor.zoomIn(currentPoint, {
  animation: {
    duration: 400,
    easing: EASINGS.easeInOutCubic
  }
})

// Multiple zoom steps
function zoomInMultiple(steps: number) {
  for (let i = 0; i < steps; i++) {
    setTimeout(() => {
      editor.zoomIn(editor.getViewportScreenCenter())
    }, i * 200)
  }
}

Camera and Viewport Info

// Get current camera state
const camera = editor.getCamera()
console.log(`Position: ${camera.x}, ${camera.y}, Zoom: ${camera.z}`)

// Get zoom level
const zoomLevel = editor.getZoomLevel() // 1.0 = 100%

// Get viewport bounds in page space
const viewportPageBounds = editor.getViewportPageBounds()

// Get viewport center
const center = editor.getViewportPageCenter()

See Also