Events
LibreDraw emits events during drawing and editing operations. Subscribe and unsubscribe using the on and off methods.
Event Map
interface LibreDrawEventMap {
create: CreateEvent;
update: UpdateEvent;
delete: DeleteEvent;
split: SplitEvent;
splitfailed: SplitFailedEvent;
setback: SetbackEvent;
setbackfailed: SetbackFailedEvent;
selectionchange: SelectionChangeEvent;
modechange: ModeChangeEvent;
draftchange: DraftChangeEvent;
}create
Emitted when a new feature is created. In draw-point mode this happens on each click/tap. In draw-line mode it happens when the line is finalized. In draw mode it happens when the polygon is completed.
Payload: CreateEvent
interface CreateEvent {
feature: LibreDrawFeature;
}| Property | Type | Description |
|---|---|---|
feature | LibreDrawFeature | The newly created Point, LineString, or Polygon feature |
Example
draw.on('create', (e) => {
console.log('New feature:', e.feature.id, e.feature.geometry.type);
if (e.feature.geometry.type === 'Polygon') {
console.log('Vertices:', e.feature.geometry.coordinates[0].length - 1);
}
});update
Emitted when an existing feature is modified. This includes polygon vertex edits, polygon dragging, and point dragging in select mode.
Payload: UpdateEvent
interface UpdateEvent {
feature: LibreDrawFeature;
oldFeature: LibreDrawFeature;
}| Property | Type | Description |
|---|---|---|
feature | LibreDrawFeature | The updated Point, LineString, or Polygon feature (new state) |
oldFeature | LibreDrawFeature | The feature before the update (previous state) |
Example
draw.on('update', (e) => {
console.log('Feature updated:', e.feature.id, e.feature.geometry.type);
console.log('Old coordinates:', e.oldFeature.geometry.coordinates);
console.log('New coordinates:', e.feature.geometry.coordinates);
});delete
Emitted when a feature is deleted (via toolbar button, Delete key, or deleteFeature() API).
Payload: DeleteEvent
interface DeleteEvent {
feature: LibreDrawFeature;
}| Property | Type | Description |
|---|---|---|
feature | LibreDrawFeature | The deleted Point, LineString, or Polygon feature |
Example
draw.on('delete', (e) => {
console.log('Feature deleted:', e.feature.id, e.feature.geometry.type);
});split
Emitted when a polygon is successfully split into two polygons.
Payload: SplitEvent
interface SplitEvent {
originalFeature: LibreDrawFeature;
features: [LibreDrawFeature, LibreDrawFeature];
}| Property | Type | Description |
|---|---|---|
originalFeature | LibreDrawFeature | The source polygon before split |
features | [LibreDrawFeature, LibreDrawFeature] | The two resulting polygons |
Example
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
type SplitFailReason =
| 'same-points'
| 'insufficient-vertices'
| 'has-holes'
| 'invalid-intersection-count'
| 'self-intersecting-result';
interface SplitFailedEvent {
reason: SplitFailReason;
featureId: string;
}| Property | Type | Description |
|---|---|---|
reason | SplitFailReason | Reason of split failure |
featureId | string | Target feature ID |
Example
draw.on('splitfailed', (e) => {
console.warn('Split failed:', e.reason, e.featureId);
});setback
Emitted when a setback operation succeeds.
Payload: SetbackEvent
interface SetbackEvent {
originalFeature: LibreDrawFeature;
feature: LibreDrawFeature;
edgeIndex: number;
distance: number;
}| Property | Type | Description |
|---|---|---|
originalFeature | LibreDrawFeature | The source polygon before setback |
feature | LibreDrawFeature | Result polygon after setback |
edgeIndex | number | Applied edge index |
distance | number | Setback distance in meters |
Example
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
type SetbackFailReason = 'has-holes' | 'invalid-split';
interface SetbackFailedEvent {
reason: SetbackFailReason;
featureId: string;
}| Property | Type | Description |
|---|---|---|
reason | SetbackFailReason | Reason of setback failure |
featureId | string | Target feature ID |
Example
draw.on('setbackfailed', (e) => {
console.warn('Setback failed:', e.reason, e.featureId);
});selectionchange
Emitted when the set of selected features changes.
Payload: SelectionChangeEvent
interface SelectionChangeEvent {
selectedIds: string[];
}| Property | Type | Description |
|---|---|---|
selectedIds | string[] | Array of currently selected feature IDs. Empty array when nothing is selected. |
Example
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
interface ModeChangeEvent {
mode: ModeName;
previousMode: ModeName;
}| Property | Type | Description |
|---|---|---|
mode | ModeName | The new active mode ('idle', 'draw-point', 'draw-line', 'draw', 'select', 'split', or 'setback') |
previousMode | ModeName | The previous mode |
Example
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');
});draftchange
Emitted whenever the in-progress draft of a drawing mode ('draw' or 'draw-line') changes.
Fires when:
- A vertex is added via pointer-down
- A vertex is removed (long-press, or the auto-pop during double-click finalization)
- The draft is finalized — via double-click, close-on-first-vertex, or
finishDrawing()— withvertexCount: 0 - The draft is discarded — via Escape or
cancelDrawing()— withvertexCount: 0 - The active mode transitions away from a drawing mode (deactivation), with
vertexCount: 0
Payload: DraftChangeEvent
interface DraftChangeEvent {
vertexCount: number;
}| Property | Type | Description |
|---|---|---|
vertexCount | number | The number of vertices in the current draft (0 after finalization, cancellation, or mode exit) |
Example
draw.on('draftchange', (e) => {
// Enable a finish button once the polygon has enough vertices
finishBtn.disabled = e.vertexCount < 3;
vertexCountLabel.textContent = `Vertices: ${e.vertexCount}`;
});Removing Listeners
Use off with the same function reference to remove a listener:
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:
// 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);