Mapbox GL How to create custom control?
Asked Answered
C

3

15

I want to create custom control using Mapbox gl Api. I'm trying to extend Control class and add my own functionality. It doesn't seem working. I'm getting TypeError: "x" is not a constructor error in my console. Even though after extending the class, I'm using super() in constructor function. Am I doing it wrong, is there any other way how to create custom control ?

Connecticut answered 20/10, 2016 at 19:10 Comment(1)
can you post how you ended up doing this?Flossie
B
27

Your custom control for Mapbox should implement the next interface:

  • onAdd(map) — a function that takes map object and should return your control object. It will be called when your control is added to the map.

  • onRemove(map) — a function that takes map object and will be called when control is removed from the map. You can unbind your event listeners in this method.

Here is a CodePen example. Just use your access token.

Bisector answered 13/9, 2017 at 10:26 Comment(2)
Thanks. Any example how to add a button with click event?Reflectance
Ok. As I find out if you add a class name mapboxgl-ctrl this.container.className = ‘mapboxgl-ctrl’; - then everything works like a charmReflectance
L
10

Here is a fully fleshed out version of Артём Ощепков's answer to create a home button.

const homePosition = {
  center: [144, -37],
};

function addHomeButton(map) {
  class HomeButton {
    onAdd(map) {
      const div = document.createElement("div");
      div.className = "mapboxgl-ctrl mapboxgl-ctrl-group";
      div.innerHTML = `<button>
        <svg focusable="false" viewBox="0 0 24 24" aria-hidden="true" style="font-size: 20px;"><title>Reset map</title><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"></path></svg>
        </button>`;
      div.addEventListener("contextmenu", (e) => e.preventDefault());
      div.addEventListener("click", () => map.flyTo(homePosition));

      return div;
    }
  }
  const homeButton = new HomeButton();
  map.addControl(homeButton, "bottom-right");
}
Lungan answered 2/11, 2022 at 2:56 Comment(1)
This was very useful. Thanks! Small note to make sure the button element has the attributes to match the other controls and for accessibility.: <button type="button" title="Re-center map" aria-label="Re-center map" aria-disabled="false">Proudman
P
8

Code for a control which looks like Mapbox's one is:

  onAdd(map) {
    this._map = map;
    this._container = document.createElement('div');
    this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group';
    this._container.addEventListener('contextmenu', (e) => e.preventDefault());
    this._container.addEventListener('click', (e) => this.onClick());

    this._container.innerHTML =
      '<div class="tools-box">' +
      '<button>' +
      '<span class="mapboxgl-ctrl-icon my-image-button" aria-hidden="true" title="Description"></span>' +
      '</button>' +
      '</div>';

    return this._container;
  }

And css of my-image-button is


.my-image-button {
  background: url("data:image/png;base64 etc...");
}

With "home" icon it looks like this:

Custom control with image for mapbox

Pentacle answered 12/8, 2022 at 11:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.