Transition Layers with Zoom

This example uses the ZoomRange component and zoomTransition function to fade smoothly between states and counties as the map zooms.

Current Zoom: 4.0

Interactive map data

center: -98.137,40.137
zoom: 4
pitch: 0
bearing: 0
minZoom: 0
maxZoom: 22
bounds: undefined
svelte
<MapLibre
  style="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
  class={mapClasses}
  standardControls
  center={[-98.137, 40.137]}
  zoom={4}
  on:zoomend={({ detail: { map } }) => (currentZoom = map.getZoom())}
  filterLayers={(l) => !isTextLayer(l, 'carto')}
>
  <ZoomRange maxzoom={zoomThreshold + 0.5}>
    {@const fadeStates = zoomTransition(zoomThreshold - 1, 0.8, zoomThreshold + 0.5, 0)}
    {@const fadeStatesText = zoomTransition(zoomThreshold - 1, 1, zoomThreshold, 0.2)}
    <GeoJSON id="states" data={states} promoteId="GEOID">
      <FillLayer
        paint={{
          'fill-color': 'green',
          'fill-opacity': fadeStates,
        }}
      />

      <LineLayer
        paint={{
          'line-color': 'white',
          'line-width': 1,
          'line-opacity': fadeStates,
        }}
      />
    </GeoJSON>

    <GeoJSON id="state-centers" data={stateCenters} promoteId="GEOID">
      <SymbolLayer
        filter={['!=', ['get', 'STUSPS'], 'DC']}
        paint={{
          'text-color': '#333',
          'text-opacity': fadeStatesText,
          'text-halo-color': '#eee',
          'text-halo-width': 0.5,
          'text-halo-blur': 0.5,
        }}
        layout={{
          'text-allow-overlap': true,
          'text-field': ['get', 'STUSPS'],
          'text-size': zoomTransition(3, 16, 5, 24),
        }}
      />
    </GeoJSON>
  </ZoomRange>

  <ZoomRange minzoom={zoomThreshold - 0.5}>
    {@const fadeCounties = zoomTransition(zoomThreshold - 0.5, 0, zoomThreshold + 0.5, 0.8)}
    {@const fadeCountiesText = zoomTransition(zoomThreshold, 0.2, zoomThreshold + 0.5, 1)}
    <GeoJSON id="counties" data={counties} promoteId="GEOID">
      <FillLayer
        paint={{
          'fill-color': 'orange',
          'fill-opacity': fadeCounties,
        }}
      />

      <LineLayer
        paint={{
          'line-color': 'white',
          'line-width': 1,
          'line-opacity': fadeCounties,
        }}
      />
    </GeoJSON>

    <GeoJSON id="county-centers" data={countyCenters} promoteId="GEOID">
      <SymbolLayer
        paint={{
          'text-color': 'black',
          'text-opacity': fadeCountiesText,
        }}
        layout={{
          'text-field': ['get', 'NAME'],
          'text-size': zoomTransition(5, 12, 10, 24),
        }}
      />
    </GeoJSON>
  </ZoomRange>
</MapLibre>

Back to Examples

Github