Skip to content

Events

LibreDraw emits events during drawing and editing operations. Subscribe and unsubscribe using the on and off methods.

Event Map

ts
interface LibreDrawEventMap {
  create: CreateEvent;
  update: UpdateEvent;
  delete: DeleteEvent;
  split: SplitEvent;
  splitfailed: SplitFailedEvent;
  setback: SetbackEvent;
  setbackfailed: SetbackFailedEvent;
  selectionchange: SelectionChangeEvent;
  modechange: ModeChangeEvent;
}

create

Emitted when a new polygon is created (user completes drawing with double-click/double-tap). The active mode remains draw after creation, so users can continue drawing.

Payload: CreateEvent

ts
interface CreateEvent {
  feature: LibreDrawFeature;
}
PropertyTypeDescription
featureLibreDrawFeatureThe newly created polygon feature

Example

ts
draw.on('create', (e) => {
  console.log('New polygon:', e.feature.id);
  console.log('Vertices:', e.feature.geometry.coordinates[0].length - 1);

  // Save to your backend
  await savePolygon(e.feature);
});

update

Emitted when an existing polygon is modified (vertex moved, vertex added/removed, polygon dragged).

Payload: UpdateEvent

ts
interface UpdateEvent {
  feature: LibreDrawFeature;
  oldFeature: LibreDrawFeature;
}
PropertyTypeDescription
featureLibreDrawFeatureThe updated polygon feature (new state)
oldFeatureLibreDrawFeatureThe polygon feature before the update (previous state)

Example

ts
draw.on('update', (e) => {
  console.log('Polygon updated:', e.feature.id);
  console.log('Old coordinates:', e.oldFeature.geometry.coordinates);
  console.log('New coordinates:', e.feature.geometry.coordinates);
});

delete

Emitted when a polygon is deleted (via toolbar button, Delete key, or deleteFeature() API).

Payload: DeleteEvent

ts
interface DeleteEvent {
  feature: LibreDrawFeature;
}
PropertyTypeDescription
featureLibreDrawFeatureThe deleted polygon feature

Example

ts
draw.on('delete', (e) => {
  console.log('Polygon deleted:', e.feature.id);

  // Remove from your backend
  await removePolygon(e.feature.id);
});

split

Emitted when a polygon is successfully split into two polygons.

Payload: SplitEvent

ts
interface SplitEvent {
  originalFeature: LibreDrawFeature;
  features: [LibreDrawFeature, LibreDrawFeature];
}
PropertyTypeDescription
originalFeatureLibreDrawFeatureThe source polygon before split
features[LibreDrawFeature, LibreDrawFeature]The two resulting polygons

Example

ts
draw.on('split', (e) => {
  console.log('Split source:', e.originalFeature.id);
  console.log('Result polygons:', e.features.map((f) => f.id));
});

splitfailed

Emitted when split operation fails.

Payload: SplitFailedEvent

ts
type SplitFailReason =
  | 'same-points'
  | 'insufficient-vertices'
  | 'has-holes'
  | 'invalid-intersection-count'
  | 'self-intersecting-result';

interface SplitFailedEvent {
  reason: SplitFailReason;
  featureId: string;
}
PropertyTypeDescription
reasonSplitFailReasonReason of split failure
featureIdstringTarget feature ID

Example

ts
draw.on('splitfailed', (e) => {
  console.warn('Split failed:', e.reason, e.featureId);
});

setback

Emitted when a setback operation succeeds.

Payload: SetbackEvent

ts
interface SetbackEvent {
  originalFeature: LibreDrawFeature;
  feature: LibreDrawFeature;
  edgeIndex: number;
  distance: number;
}
PropertyTypeDescription
originalFeatureLibreDrawFeatureThe source polygon before setback
featureLibreDrawFeatureResult polygon after setback
edgeIndexnumberApplied edge index
distancenumberSetback distance in meters

Example

ts
draw.on('setback', (e) => {
  console.log('Setback applied:', e.originalFeature.id, '->', e.feature.id);
  console.log('Edge:', e.edgeIndex, 'Distance(m):', e.distance);
});

setbackfailed

Emitted when setback operation fails.

Payload: SetbackFailedEvent

ts
type SetbackFailReason = 'has-holes' | 'invalid-split';

interface SetbackFailedEvent {
  reason: SetbackFailReason;
  featureId: string;
}
PropertyTypeDescription
reasonSetbackFailReasonReason of setback failure
featureIdstringTarget feature ID

Example

ts
draw.on('setbackfailed', (e) => {
  console.warn('Setback failed:', e.reason, e.featureId);
});

selectionchange

Emitted when the set of selected features changes.

Payload: SelectionChangeEvent

ts
interface SelectionChangeEvent {
  selectedIds: string[];
}
PropertyTypeDescription
selectedIdsstring[]Array of currently selected feature IDs. Empty array when nothing is selected.

Example

ts
draw.on('selectionchange', (e) => {
  if (e.selectedIds.length > 0) {
    console.log('Selected:', e.selectedIds);
    // Enable delete button in your UI
    deleteButton.disabled = false;
  } else {
    console.log('Selection cleared');
    deleteButton.disabled = true;
  }
});

modechange

Emitted when the active mode changes.

Payload: ModeChangeEvent

ts
interface ModeChangeEvent {
  mode: ModeName;
  previousMode: ModeName;
}
PropertyTypeDescription
modeModeNameThe new active mode ('idle', 'draw', 'select', 'split', or 'setback')
previousModeModeNameThe previous mode

Example

ts
draw.on('modechange', (e) => {
  console.log(`${e.previousMode} → ${e.mode}`);

  // Update your UI based on mode
  drawButton.classList.toggle('active', e.mode === 'draw');
  selectButton.classList.toggle('active', e.mode === 'select');
  splitButton.classList.toggle('active', e.mode === 'split');
  setbackButton.classList.toggle('active', e.mode === 'setback');
});

Removing Listeners

Use off with the same function reference to remove a listener:

ts
const onCreateHandler = (e: CreateEvent) => {
  console.log(e.feature);
};

// Subscribe
draw.on('create', onCreateHandler);

// Unsubscribe
draw.off('create', onCreateHandler);

WARNING

Arrow functions defined inline cannot be removed. Always store a reference:

ts
// This CANNOT be removed later
draw.on('create', (e) => console.log(e));

// This CAN be removed later
const handler = (e: CreateEvent) => console.log(e);
draw.on('create', handler);
draw.off('create', handler);

Released under the MIT License.