Menu

Element Binding System

Relevant source files

Purpose and Scope

The Element Binding System manages the attachment relationships between elements in Excalidraw. This system handles two primary binding types: arrow-to-element bindings (connecting arrow endpoints to shapes) and text-to-container bindings (attaching text elements inside shapes). The system maintains binding metadata, detects eligible binding targets, updates bound elements during transformations, and repairs broken bindings during data restoration.

For information about element creation and lifecycle, see Element Types and Creation. For details on element transformations, see Element Properties and Transformations.


Binding Types and Data Structures

Binding Type Hierarchy

Sources: packages/element/src/binding.ts1-100 packages/excalidraw/data/restore.ts52-86

Binding Data Structures

StructurePropertiesUsage
PointBindingelementId, focus, gapStandard arrow-to-element binding
FixedPointBindingextends PointBinding + fixedPoint: [x, y]Elbow arrow bindings with fixed attachment points
boundElementsArray of {id: string, type: 'arrow'|'text'}Tracks elements bound to a container
containerIdstring | nullText element reference to its container

Sources: packages/element/src/binding.ts70-85 packages/excalidraw/data/restore.ts60-66


Arrow-to-Element Binding

Binding Detection Flow

Sources: packages/element/src/binding.ts97-105 packages/element/src/binding.ts574-658

Binding Parameters

The PointBinding structure stores three key parameters:

For elbow arrows, FixedPointBinding adds:

Sources: packages/element/src/binding.ts480-528 packages/element/src/binding.ts704-734

Binding and Unbinding Operations

The system ensures bidirectional consistency:

  1. Arrow stores startBinding/endBinding with target element ID
  2. Target element stores arrow ID in its boundElements array
  3. Updates to either side trigger corresponding updates on the other side

Sources: packages/element/src/binding.ts124-217 packages/element/src/binding.ts480-528 packages/element/src/binding.ts560-572

Binding During Element Dragging

Drag TypeStrategyImplementation
Arrow endpointsRe-evaluate bindings for dragged endpointsgetBindingStrategyForDraggingArrowEndpoints() packages/element/src/binding.ts243-279
Arrow shaftKeep bindings if still close to original elementsgetBindingStrategyForDraggingArrowOrJoints() packages/element/src/binding.ts281-322
Elbow arrowsNo rebinding during dragReturns ["keep", "keep"] packages/element/src/binding.ts289-291

Sources: packages/element/src/binding.ts324-353


Text-to-Container Binding

Text Binding Structure

Sources: packages/excalidraw/actions/actionBoundText.tsx1-221 packages/element/src/textElement.ts1-50

Binding Lifecycle

The text binding lifecycle follows these steps:

  1. Creation: actionBindText validates that exactly one text element and one compatible container are selected packages/excalidraw/actions/actionBoundText.tsx108-138

  2. Binding: Sets textElement.containerId and adds text reference to container.boundElements packages/excalidraw/actions/actionBoundText.tsx155-167

  3. Positioning: computeBoundTextPosition() calculates centered position within container packages/element/src/textElement.ts400-500

  4. Resizing: redrawTextBoundingBox() adjusts text dimensions to fit container with padding packages/element/src/textElement.ts600-700

  5. Maintenance: handleBindTextResize() updates container dimensions when text changes packages/element/src/textElement.ts800-900

Sources: packages/excalidraw/actions/actionBoundText.tsx53-105 packages/excalidraw/actions/actionBoundText.tsx139-180

Text Container Constraints

Sources: packages/excalidraw/actions/actionBoundText.tsx222-300 packages/element/src/textElement.ts200-350


Binding Eligibility and Detection

Eligibility Criteria

The getHoveredElementForBinding() function determines which element (if any) should be bound to at a given pointer position:

Sources: packages/element/src/binding.ts574-658 packages/element/src/binding.ts660-702

Border Testing

The bindingBorderTest() function checks if a point is within the binding activation distance of an element's border:

  • Threshold: FIXED_BINDING_DISTANCE (5 pixels) packages/element/src/binding.ts107
  • Fullshape mode: For solid filled elements, entire area is valid (not just border)
  • Frame elements: Fullshape disabled to allow binding to frame children
  • Distance calculation: Uses distanceToElement() for precise border distance

Sources: packages/element/src/binding.ts1251-1290 packages/element/src/distance.ts29-53


Binding Maintenance and Updates

Update Triggers

Bound elements must be updated when their bound targets change:

Sources: packages/element/src/binding.ts736-859 packages/element/src/binding.ts861-878

Binding Update Algorithm

The updateBoundElements() function follows this algorithm for each bound arrow:

  1. Check if update needed: doesNeedUpdate() verifies the arrow binds to the changed element packages/element/src/binding.ts880-888

  2. Adjust gap for scaling: If container was resized, maybeCalculateNewGapWhenScaling() proportionally adjusts binding gap packages/element/src/binding.ts1292-1316

  3. Calculate new point: updateBoundPoint() computes new arrow endpoint position based on updated binding packages/element/src/binding.ts1318-1377

  4. Update arrow geometry: LinearElementEditor.movePoints() updates arrow points and bound text position packages/element/src/binding.ts845-852

  5. Handle bound text: If arrow has bound text, handleBindTextResize() repositions it packages/element/src/binding.ts854-857

Sources: packages/element/src/binding.ts738-858

Simultaneous Updates

When multiple elements are updated simultaneously (e.g., during group transformations), the system optimizes binding updates:

Sources: packages/element/src/binding.ts890-894 packages/element/src/binding.ts742-763


Elbow Arrow Fixed Point Bindings

Fixed Point Calculation

Elbow arrows use FixedPointBinding with absolute attachment coordinates instead of relative focus values:

Sources: packages/element/src/binding.ts1102-1249 packages/excalidraw/data/restore.ts124-156

Fixed Point vs Standard Binding

AspectStandard PointBindingFixedPointBinding (Elbow)
Position storageRelative focus (-1 to 1)Absolute fixedPoint [x, y]
AttachmentCalculated from focus along borderFixed to specific coordinates
UpdatingRecalculate from focus on changesUpdate routing but keep fixedPoint
SnappingNot snappedSnapped to grid/edges/midpoints
RepairUse repairBinding()Use normalizeFixedPoint()

Sources: packages/element/src/binding.ts469-478 packages/excalidraw/data/restore.ts136-148

Elbow Arrow Binding Rules

Elbow arrows have special binding behavior:

Sources: packages/element/src/binding.ts281-291 packages/excalidraw/data/restore.ts628-693


Binding Restoration and Repair

Restoration Flow

Sources: packages/excalidraw/data/restore.ts527-694

Repair Operations

The restoration system applies these repairs:

Container Element Repair (repairContainerElement):

Bound Element Repair (repairBoundElement):

Linear Element Repair:

Sources: packages/excalidraw/data/restore.ts420-625

Legacy Binding Migration

During restoration, legacy binding formats are migrated:

Sources: packages/excalidraw/data/restore.ts124-156 packages/excalidraw/data/restore.ts214-216


Integration with Other Systems

Binding in Actions

Several action handlers interact with the binding system:

ActionBinding InteractionImplementation
actionFlipHorizontal/VerticalRebinds arrows after flip transformationpackages/excalidraw/actions/actionFlip.ts161-167
actionBindTextCreates text-to-container bindingpackages/excalidraw/actions/actionBoundText.tsx108-180
actionUnbindTextRemoves text-to-container bindingpackages/excalidraw/actions/actionBoundText.tsx53-105
changePropertyUpdates bound elements after style changespackages/excalidraw/actions/actionProperties.tsx274-281

Sources: packages/excalidraw/actions/actionFlip.ts86-207 packages/excalidraw/actions/actionBoundText.tsx1-221

Binding Constants

ConstantValuePurpose
FIXED_BINDING_DISTANCE5Pixel threshold for binding detection packages/element/src/binding.ts107
BINDING_HIGHLIGHT_THICKNESS10Visual highlight thickness for bind preview packages/element/src/binding.ts108
BOUND_TEXT_PADDING20Minimum padding for text inside containers packages/common/src/constants.ts

Sources: packages/element/src/binding.ts107-108 packages/excalidraw/actions/actionBoundText.tsx2-8