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

Resize of container Issue

Open afk-mario opened this issue 7 years ago • 7 comments

Probably related to

  • https://github.com/alex3165/react-mapbox-gl/issues/445
  • https://github.com/alex3165/react-mapbox-gl/issues/372
  • https://github.com/alex3165/react-mapbox-gl/issues/395
  • https://github.com/alex3165/react-mapbox-gl/issues/130
  • https://github.com/alex3165/react-mapbox-gl/issues/32

So the structure I have is something like this

<style>
.container {
	display: flex;
	flex-flow: row nowrap;
	width: 100vw;
	height: 100vh;
}

aside {
	width: 300px;
	height: 100%;
	transition: width 0.2s ease;
}

aside.collapsed {
	 width: 0px;
}

.map {
	flex: 1 1 auto;
}
</style>


<div class="container">
	<aside>
		<span>controls</span>
	</aside>
	<div class="map">
	</div>
</div>

When I collapse the sidebar, the size of the map doesn't get updated as it should, I tried forcing a map.resize() when the sidebar is toggled, the problem is that as it has a transition I had to do this

  const sidebarAnimationDuration = 220;
  afterCollapse = () => {
    window.setTimeout(() => {
      window.dispatchEvent(new Event('resize'));
    }, sidebarAnimationDuration);
  };

  setCollapse = collapsed => {
    this.setState({ collapsed }, this.afterCollapse);
  };

Which feels like a messy hack, is there any better way of doing this ?

afk-mario avatar Dec 13 '18 19:12 afk-mario

I had this same use case and after some research found the element-resize-event library. You can use it to set up an event listener for a resize of a DOM element (e.g. a container holding your map).

For example, you could do something like this with it:

const resizeMap = () => {
    if (map) {
      map.resize();
    }
};

const mapContainer = document.getElementById('map-container');

elementResizeEvent(mapContainer, resizeMap);

wilcoxmd avatar Jul 26 '19 20:07 wilcoxmd

any update on this? the above solutions dont feel right

JClackett avatar Jul 16 '20 12:07 JClackett

@JClackett @afk-mario @wilcoxmd

This works:

import React from 'react';
import ReactMapboxGl, {Marker} from 'react-mapbox-gl';
import * as MapboxGl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';

export const MapBox = React.memo(function MapBox() {

    const Map = ReactMapboxGl({
        accessToken: 'Token',
        trackResize: true,
        
    });

    const onLoaded =(map: MapboxGl.Map) =>{
        map.resize();
    }
    
    return (
        <div className="main-map-container" style={{height: "100%"}}>
            <Map
                style="mapbox://styles/mapbox/streets-v9"
                containerStyle={{
                    height: "calc(100vh - 130px)",
                    width: "100%"
                }}
                center={[19.9449799, 50.06465]}
                zoom={[13]}
                
                onStyleLoad={(map)=>onLoaded(map)}
                onClick={()=>alert("click")}
            >
                <Marker coordinates={[19.9449799, 50.0646501]} anchor="bottom">
                    <div >test</div>
                </Marker>
            </Map>
        </div>
    );
});

Diaver avatar Nov 13 '20 04:11 Diaver

This is how I made it work, by using a ResizeObserver:

const ro = new ResizeObserver(() => {
    if (map) {
        map.resize();
    }
});

// Observe the map div container.
ro.observe(document.getElementById('map'));

If you are using Angular, you might need a polyfill for ResizeObserver, or just do:

const ro = new (window as any).ResizeObserver(() => {
    if (this.map) {
        this.map.resize();
    }
});

ro.observe(document.getElementById('map'));

ro2nie avatar Jun 24 '21 13:06 ro2nie

Hi, mate. I'm using <ReactMapGL> component in my react project. What is the map in your code above? I mean, can I use <ReactMapGL ref={myMap} and fill your ro.observe(...) with myMap.current?

KalvinWei avatar Sep 04 '21 10:09 KalvinWei

@KalvinWei

Check this tutorial: It helped me fix the window resize issue. http://vis.academy/#/building-a-geospatial-app/1-starting-with-a-map

Hope it helps you too.

sampreethamithkumar avatar Sep 06 '21 05:09 sampreethamithkumar

@KalvinWei

import * as mapboxgl from 'mapbox-gl';

const map = new mapboxgl.Map({
      container: this.htmlMapId,
      style: this.style,
      zoom: DEFAULT_ZOOM,
      center: INITIAL_COORDINATES,
      maxZoom: ZOOMED_IN_LEVEL,
      scrollZoom: {
          ctrl: true
      }
});

Then use this hook map.on('load', () => {...}); to do anything after the map finishes loading.

ro2nie avatar Sep 06 '21 13:09 ro2nie