7
votes

I'm loading points from Geojson in batches and would like to add "fadeIn" effect or animation when the points first appear in Mapbox.

this.map.addLayer({
  id: 'points',
  type: 'circle',
  paint: {
    'circle-radius-transition': {duration: 300},
    'circle-color': '#F98200',
    'circle-stroke-color': '#D23B00',
    'circle-stroke-opacity': 0.5,
  },
  source: 'points',
})

I tried circle-radius-transition but it does not seem to help.

3

3 Answers

8
votes

You are on the right track with the paint properties. I think what you need is the circle-opacity-transition.

Follow these steps:

  1. Add the points with 'circle-opacity': 0 as default opacity value
  2. Set the 'circle-opacity-transition' as you wish
  3. After the map is loaded change the layers 'circle-opacity' to 1 and your layer will be faded in.

    map.addLayer({
      "id": "point",
      "source": "point",
      "type": "circle",
      "paint": {
        "circle-radius": 20,
          // here we define defaut opacity is zero
          "circle-opacity": 0,
          "circle-opacity-transition": {duration: 2000},
          "circle-color": 'red'
          }
    });
    

You can check out this solution here: codepen

2
votes

Joel's answer was perfect but the timeout has to be places inside the map load function else the circle layer will not be loaded if the map takes more time to load

Checkout the below code snippet

mapboxgl.accessToken = 'pk.eyJ1Ijoiam9lbHN0dWVkbGUiLCJhIjoiY2ltbmI1OWNpMDAxNnV1bWFtMnpqYWJndyJ9.uDWVjgzU7EVS63OuVWSRuQ';
var map = new mapboxgl.Map({
  container: 'map', // container id
  style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
  center: [7.445683, 46.945966], // starting position
  zoom: 9 // starting zoom
});

// the data we'll add as 'points'
var data = {
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "properties": {
      "timestamp": "0",
      "location-name": "Bern"
    },
    "geometry": {
      "type": "Point",
      "coordinates": [7.445683, 46.945966]
    }
  }]
}

// so if the map loads do the following
map.on('load', function() {

  // add the data source with the information for the point
  map.addSource('point', {
    "type": "geojson",
    "data": data
  });


  map.addLayer({
    "id": "point",
    "source": "point",
    "type": "circle",
    "paint": {
      "circle-radius": 20,
      // here we define defaut opacity is zero
      "circle-opacity": 0,
      "circle-opacity-transition": {
        duration: 1500
      },
      "circle-color": 'red'
    }
  });
  //Timeout shoud be within the map load function
  setTimeout(function() {
    map.setPaintProperty('point', 'circle-opacity', 1);
  }, 1);
});
<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8' />
  <title></title>
  <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
  <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.js'></script>
  <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.css' rel='stylesheet' />
  <style>
    body {
      margin: 0;
      padding: 0;
    }
    
    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
  </style>
</head>

<body>

  <div id='map'></div>

</body>

</html>
0
votes

Unfortuntely the property-transition won't work in some cases, for example, when you want to toggle a layer on hover.

At least, in my case it does not work. This is my code, the elements pop like there's nothing.

map.addLayer({
        'id': 'places-details',
        'type': 'symbol',
        'source': 'places',
        'layout': {
            'icon-image': '{icon}',
            'text-field': '{data}',
            'icon-size': .8,
            'text-anchor': 'center',
        },
        'paint': {
            'text-color': '#ffffff',
            'icon-opacity': [
                'case',
                ['boolean', ['feature-state', 'hover'], false],
                1, 0
            ],
            'text-opacity': [
                'case',
                ['boolean', ['feature-state', 'hover'], false],
                1, 0
            ],
            "text-opacity-transition": {
              "duration": 3000,
              "delay": 0
            },
            "icon-opacity-transition": {
              "duration": 300,
              "delay": 0
            }
        },
    });