ethan
ethan

Reputation: 1971

Mapbox GL 3D building style dynamically change

I was wondering if the "fill-color" of the 3D building can be dynamically changed based on certain events, such as mouseMoveEvent when hover over a building, highlight the 3D building.

Upvotes: 3

Views: 1866

Answers (2)

Iqbal
Iqbal

Reputation: 11

Try this

map.on('load', function () {
        var layers = map.getStyle().layers;

        var labelLayerId;
        for (var i = 0; i < layers.length; i++) {
          if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
            labelLayerId = layers[i].id;
            break;
          }
        }
        map.addLayer(
          {
            'id': '3dbuildings',
            'source': 'composite',
            'source-layer': 'building',
            'filter': ['==', 'extrude', 'true'],
            'type': 'fill-extrusion',
            'minzoom': 15,
            pitch: 60,
            bearing: -60,
            'paint': {
              'fill-extrusion-color': '#aaa',

              // use an 'interpolate' expression to add a smooth transition effect to the
              // buildings as the user zooms in
              'fill-extrusion-height': [
                'interpolate',
                ['linear'],
                ['zoom'],
                15,
                0,
                15.05,
                ['get', 'height']
              ],
              'fill-extrusion-base': [
                'interpolate',
                ['linear'],
                ['zoom'],
                15,
                0,
                15.05,
                ['get', 'min_height']
              ],
              'fill-extrusion-opacity': 0.6
            }
          },
          labelLayerId
        );

        map.addSource('currentBuildings', {
          type: 'geojson',
          data: {
            "type": "FeatureCollection",
            "features": []
          }
        });

        map.addLayer(
          {
            'id': 'highlight',
            'source': 'currentBuildings',
            'filter': ['==', 'extrude', 'true'],
            'type': 'fill-extrusion',
            'minzoom': 15,
            pitch: 60,
            bearing: -60,

            'paint': {
              'fill-extrusion-color': '#f00',
              // use an 'interpolate' expression to add a smooth transition effect to the
              // buildings as the user zooms in
              'fill-extrusion-height': [
                'interpolate',
                ['linear'],
                ['zoom'],
                4,
                0,
                15.05,
                ['get', 'height']
              ],
              'fill-extrusion-base': [
                'interpolate',
                ['linear'],
                ['zoom'],
                4,
                0,
                15.05,
                ['get', 'min_height']
              ],
              'fill-extrusion-opacity': 0.6
            }
          },
          labelLayerId
        );


        map.on('click', '3dbuildings', function (e) {
          map.getSource('currentBuildings').setData({
            "type": "FeatureCollection",
            "features": e.features
          });
        });
        map.on('mousemove', '3dbuildings', function (e) {
          map.getSource('currentBuildings').setData({
            "type": "FeatureCollection",
            "features": e.features
          });
        });
      });

Upvotes: 1

Lucas Wojciechowski
Lucas Wojciechowski

Reputation: 3782

There is no built-in hover effect in GL JS. You may implement the effect yourself by

  1. adding an listener for the mousemove event
  2. finding the features underneath the mouse during the mousemove event using Map#queryRenderedFeatures
  3. using Map#setPaintProperty to change the color of the buildings / a building

You can see an example of implementing a hover effect for GL JS here: https://www.mapbox.com/mapbox-gl-js/example/hover-styles/

Upvotes: 0

Related Questions