Mapbox GL Draw
repository·main·Indexed 21 days ago
https://github.com/mapbox/mapbox-gl-drawA plugin for Mapbox GL JS that provides tools for drawing and editing geographic features such as points, lines, and polygons directly on a map. It includes a set of drawing modes (simple_select, direct_select, draw_line_string, draw_polygon, and draw_point), an API for managing GeoJSON features, and an extensible architecture for creating custom interaction modes.
What's inside @mapbox/mapbox-gl-draw
- Mapbox Draw is designed to be extensible. Instead of modifying the core library, you can implement new interactions by creating custom modes. This allows you to experiment with new drawing or editing behaviors before they are considered for the core library.
Understand MapboxDraw modes
mainMapboxDraw operates in different modes that define user interaction. Mode names are available via the
Draw.modesenum.simple_select(Draw.modes.SIMPLE_SELECT): Default mode. Allows selecting, deleting, and dragging features.direct_select(Draw.modes.DIRECT_SELECT): Allows selecting, deleting, and dragging vertices of a selected line or polygon. Triggered when a user clicks a vertex insimple_selectmode.draw_line_string(Draw.modes.DRAW_LINE_STRING): Mode for drawing a LineString feature.draw_polygon(Draw.modes.DRAW_POLYGON): Mode for drawing a Polygon feature.draw_point(Draw.modes.DRAW_POINT): Mode for drawing a Point feature.
How modes work in Mapbox Draw
mainIn Mapbox Draw, modes are abstractions used to group sets of user interactions into a single behavior. For example, the built-in
draw_polygonmode manages all interactions required to draw a polygon, whilesimple_selectmanages interactions for selecting features.Developers can extend Mapbox Draw by writing custom modes and registering them via the
modesoption in theMapboxDrawconstructor. This allows for complete control over how map interactions (clicks, drags, key presses) translate into drawing or editing actions.var draw = new MapboxDraw({ defaultMode: 'my_custom_mode', modes: Object.assign({ my_custom_mode: MyCustomMode, }, MapboxDraw.modes), });Import @mapbox/mapbox-gl-draw
mainDepending on your environment, use one of the following methods to import the library.
When using modules:
import mapboxgl from 'mapbox-gl'; import MapboxDraw from "@mapbox/mapbox-gl-draw";When using a CDN:
<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.js'></script>Include @mapbox/mapbox-gl-draw CSS
mainMapbox Draw requires its CSS to be included in your build to render correctly.
When using modules: Import the CSS file directly in your JavaScript entry point.
When using CDN: Include the stylesheet link in your HTML.
// When using modules import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'<!-- When using CDN --> <link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.css' type='text/css' />Write a custom mode for Mapbox Draw
mainTo create a custom mode, define an object containing lifecycle functions.
toDisplayFeatures(Required): This is the only mandatory function. It decides which features from the data store are rendered on the map. It receives the currentgeojsonand adisplaycallback function. You must calldisplay(geojson)(or pass modified versions) to ensure features appear on the map.onSetup: Triggered when transitioning into the mode. It receivesopts(passed viadraw.changeMode('mode', opts)) and should return astateobject. Thisstateobject is then passed as the first argument to all other lifecycle functions.- Interaction Handlers: Implement functions like
onClick,onDrag,onMouseMove,onKeyDown, etc., to respond to user input. Within these, you can usethis.newFeature(geojson)to create aDrawFeatureandthis.addFeature(feature)to add it to the map. - Mode Switching: Use
this.changeMode('mode_name')within a lifecycle function to transition to a different mode (e.g., returning tosimple_select).
var LotsOfPointsMode = {}; // 1. Setup state LotsOfPointsMode.onSetup = function(opts) { var state = {}; state.count = opts.count || 0; return state; }; // 2. Handle interactions LotsOfPointsMode.onClick = function(state, e) { var point = this.newFeature({ type: 'Feature', properties: { count: state.count }, geometry: { type: 'Point', coordinates: [e.lngLat.lng, e.lngLat.lat] } }); this.addFeature(point); }; LotsOfPointsMode.onKeyUp = function(state, e) { if (e.keyCode === 27) return this.changeMode('simple_select'); }; // 3. Required: Define how to render LotsOfPointsMode.toDisplayFeatures = function(state, geojson, display) { display(geojson); }; // 4. Register the mode var draw = new MapboxDraw({ defaultMode: 'lots_of_points', modes: Object.assign({ lots_of_points: LotsOfPointsMode, }, MapboxDraw.modes), });Install @mapbox/mapbox-gl-draw
mainInstall the package using npm. Note that this library requires
mapbox-glas a dependency.npm install @mapbox/mapbox-gl-drawInitialize and add MapboxDraw to a Mapbox GL JS map
mainTo use Draw, you must first create a Mapbox GL JS map instance, then instantiate
MapboxDrawwith your desired options, and finally add the Draw control to the map usingmap.addControl().Important: You must only interact with the Draw API (e.g., calling
.add()) after the map'sloadevent has fired.// Create a Mapbox GL JS map var map = new Map(mapOptions); // Create a Draw control var draw = new MapboxDraw(drawOptions); // Add the Draw control to your map map.addControl(draw); // Interact with Draw only after the map has loaded map.on('load', function() { draw.add({ .. }); });Listen to Mapbox GL Draw events
mainAll events emitted by Draw are namespaced with
draw.and are emitted from the Mapbox GL JS map object. These events are triggered by user interactions.Note on Programmatic Calls: If you invoke a Draw API function programmatically (e.g.,
draw.delete()), the event directly corresponding to that function (e.g.,draw.delete) will not fire. However, subsequent indirect events (e.g.,draw.selectionchange) may still fire.To listen for events, use the standard Mapbox GL JS
.on()method on your map instance.map.on('draw.create', function (e) { console.log(e.features); });Style Mapbox GL Draw layers
mainDraw uses a Mapbox GL Style. When creating custom styles for Draw, follow these rules:
- Do NOT provide a
source: Draw manages its own sources (mapbox-gl-draw-hotandmapbox-gl-draw-cold) to optimize performance. It will provide a source for you automatically. - You MUST provide an
id: Draw will append.hotand.coldsuffixes to your provided ID.
Available Feature Properties for Styling:
Property Values Description metafeature,midpoint,vertexmidpointandvertexare used for handles;featureis used for all features.activetrue,false(strings)Indicates if a feature is 'selected' in the current mode. modesimple_select,direct_select,draw_point,draw_line_string,draw_polygonThe current Draw mode. If
opts.userPropertiesis set totrue, user properties are available via theuser_prefix.- Do NOT provide a
Add @types/mapbox__mapbox-gl-draw for TypeScript
mainTypeScript definition files are available via DefinitelyTyped. Install them using npm to get type support.
npm install @types/mapbox__mapbox-gl-drawConfigure MapboxDraw options
mainWhen instantiating
MapboxDraw, you can pass an optional configuration object. All options are optional:keybindings(boolean, default:true): Enable/disable keyboard interactions.touchEnabled(boolean, default:true): Enable/disable touch interactions.boxSelect(boolean, default:true): Enable/disable box selection viashift+click+drag.clickBuffer(number, default:2): Pixel radius around features/vertices for click response.touchBuffer(number, default:25): Pixel radius around features/vertices for touch response.controls(Object): Toggle individual controls:point,line_string,polygon,trash,combine_features, anduncombine_features.displayControlsDefault(boolean, default:true): The default state for thecontrolsobject.styles(Array<Object>): Custom map styles for Draw features.modes(Object): Override default modes with custom ones.defaultMode(string, default:'simple_select'): The initial mode the user enters.userProperties(boolean, default:false): If true, feature properties are prefixed withuser_for styling (e.g.,['==', 'user_custom_label', 'Example']).suppressAPIEvents(boolean, default:true): Iffalse, Draw will emit events when API methods are called.