Skip to content

Changes to transform via setMinZoom or setMaxZoom can be superseded by stale transform copy when using transformCameraUpdate #6766

@Auspicus

Description

@Auspicus

maplibre-gl-js version: 5.13.0

browser: N/A

Steps to Trigger Behavior

  1. Change min or max zoom via setMinZoom / setMaxZoom, ensuring zoom is updated due to it being outside of new bounds
  2. Zoom out via scroll
  3. Note that sometimes the previous state of the transform is re-instated, resetting your zoom, etc.
transform-stale-copy-720.mov

Link to Demonstration

https://stackblitz.com/edit/vitejs-vite-drzrraph

<!DOCTYPE html>
<html lang="en">

<head>
    <script src=""></script>
    <link href="https://esm.sh/[email protected]/dist/maplibre-gl.css" rel="stylesheet">
    </link>
    <style>
        body {
            margin: 0;
        }

        #app {
            position: relative;
            height: 100vh;
            width: 100vw;
        }

        #map {
            width: 100%;
            height: 100%;
        }

        #change-zoom {
            position: absolute;
            top: 1rem;
            left: 1rem;
            z-index: 100;
        }

        #current-zoom {
            position: absolute;
            z-index: 100;
            font-size: 0.8rem;
            background-color: white;
            padding: 0.25rem;
            bottom: 1rem;
            left: 1rem;
        }
    </style>
</head>

<body>
    <div id="app">
        <button id="change-zoom">Change Zoom</button>
        <div id="map"></div>
        <div id="current-zoom"></div>
    </div>
    <script type="module">
        import maplibre from 'https://esm.sh/[email protected]'

        const map = new maplibre.Map({
            container: 'map',
            style: {
                name: 'MapLibre',
                layers: [
                    {
                        id: 'satellite',
                        type: 'raster',
                        source: 'maplibre',
                    },
                ],
                sources: {
                    maplibre: {
                        tiles: [
                            'https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
                        ],
                        type: 'raster',
                    },
                },
                version: 8,
            },
            center: [151.18068748043615, -33.96434511002358],
            zoom: 5,
            minZoom: 5,
            maxZoom: 18,
            transformCameraUpdate: (t) => t,
        });

        map.on('render', (e) => {
            const minZoom = e.target.getMinZoom();
            const maxZoom = e.target.getMaxZoom();
            const zoom = e.target.getZoom();
            document.querySelector(
                '#current-zoom'
            ).innerHTML = `${minZoom} - ${maxZoom} (${zoom})`;
        });

        document.querySelector('#change-zoom').addEventListener('click', () => {
            const currentMinZoom = map.getMinZoom();
            map.setMinZoom(currentMinZoom === 5 ? 8 : 5);
            map.setMaxZoom(currentMinZoom === 5 ? 16 : 18);
        });
    </script>
</body>

</html>

Expected Behavior

transform continues to move forward and does not revert to old copies

Actual Behavior

transform reverts to old copies which resets changes made

See downstream bug report: visgl/react-map-gl#2565 which I will close now that I can reproduce with vanilla Maplibre.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions