Resize of container Issue
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 ?
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);
any update on this? the above solutions dont feel right
@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>
);
});
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'));
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
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.
@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.