mapbox-gl-js icon indicating copy to clipboard operation
mapbox-gl-js copied to clipboard

Allow a default lightPreset value

Open JamesChevalier opened this issue 1 year ago • 0 comments

Motivation

Related to https://github.com/mapbox/mapbox-gl-js/issues/12841

Currently, setting the map theme is done after the style is loaded:

map.on('style.load', () => {
  map.setConfigProperty('basemap', 'lightPreset', 'night')
})

One issue with waiting for the style to load before setting the lightPreset value is that if you want a default 'night' then you get a flash of light gray #f3f0ef before it sets the colors for the 'night' style. This flash of gray occurs on initial map load as well as when switching back and forth between styles e.g. satellite.

Design Alternatives

The current workaround is to provide a full style hash while initializing the map:

const map = new mapboxgl.Map({
  center: [29, 29],
  container: 'map',
  minZoom: 1,
  projection: 'mercator',
  zoom: 1,
  style: {
    version: 8,
    imports: [
      {
        id: 'basemap',
        url: 'mapbox://styles/mapbox/standard',
        config: {
          lightPreset: 'night',
        }
      }
    ],
    sources: {},
    layers: []
  }
})

If there's code in place that changes lightPreset to 'day' for some visitors (e.g. a site setting to choose day/night/system themes) then their version of the map will get a brief flash of a dark color, but it feels a bit less impactful than the reverse. ~~My main worry with this approach is whatever that version is, because changing it breaks the map. I'm unsure if the expectation of 8 is hard coded in the version of Mapbox GL JS in use, or if that's set/expected in a place independent of package updates.~~ The version is just required to be 8 🤷

If lightPreset was a top-level configuration option on the Map (along with bearing, center, etc), the map could initially load in the chosen color theme and we wouldn't receive flashes of the opposite color.

Design

Mock-Up

const map = new mapboxgl.Map({
  center: [29, 29],
  container: 'map',
  minZoom: 1,
  projection: 'mercator',
  zoom: 1,
  lightPreset: 'night'
})

Concepts

Implementation

🤷 I don't know enough of the internal code to know how to implement this or - to be fair - whether it's possible in the current state.

JamesChevalier avatar Dec 07 '23 18:12 JamesChevalier