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;
}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
interface CreateEvent {
feature: LibreDrawFeature;
}| Property | Type | Description |
|---|---|---|
feature | LibreDrawFeature | The newly created polygon feature |
Example
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
interface UpdateEvent {
feature: LibreDrawFeature;
oldFeature: LibreDrawFeature;
}| Property | Type | Description |
|---|---|---|
feature | LibreDrawFeature | The updated polygon feature (new state) |
oldFeature | LibreDrawFeature | The polygon feature before the update (previous state) |
Example
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
interface DeleteEvent {
feature: LibreDrawFeature;
}| Property | Type | Description |
|---|---|---|
feature | LibreDrawFeature | The deleted polygon feature |
Example
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
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', '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');
});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);