如何调整下面的代码,以便在我调整浏览器/屏幕大小时调整 map 大小? (第一次在没有高级开发人员帮助的情况下使用 Mapbox)。
根据我自己的研究,有一些代码库可以在 map 容器上添加一个事件监听器并监听它以调整大小,然后我可以以编程方式调用 map.resize()。但是,我想知道什么是最佳实践,因为那样感觉有点老套。
代码
const applyToArray = (func, array) => func.apply(Math, array)
const getBoundsForPoints = (points) => {
console.log('Points:', points)
// Calculate corner values of bounds
const pointsLong = points.map(point => point.geometry.coordinates[0])
const pointsLat = points.map(point => point.geometry.coordinates[1])
const cornersLongLat = [
[applyToArray(Math.min, pointsLong), applyToArray(Math.min, pointsLat)],
[applyToArray(Math.max, pointsLong), applyToArray(Math.max, pointsLat)]
]
// Use WebMercatorViewport to get center longitude/latitude and zoom
const viewport = new WebMercatorViewport({ width: 600, height: 600 })
// @ts-ignore
.fitBounds(cornersLongLat, { padding: {top:20, bottom: 90, left:20, right:20} })
const { longitude, latitude, zoom } = viewport
return { longitude, latitude, zoom }
}
const myMap = () => {
const bounds = getBoundsForPoints(parkData.features);
const [viewport, setViewport] = useState({
width: "100%",
height: "600px",
...bounds
});
const [selectedPark, setSelectedPark] = useState(null);
return (
<div>
<ReactMapGL
{...viewport}
mapboxApiAccessToken="pk.eyJ1IjoiYmVubmtpbmd5IiwiYSI6ImNrY2ozMnJ5dzBrZ28ycnA1b2Vqb2I0bXgifQ.ZOaVtzsDQOrAovh9Orh13Q"
mapStyle="mapbox://styles/mapbox/streets-v11"
onViewportChange={viewport => {
setViewport(viewport);
}}
>
{parkData.features.map(park => (
<Marker
key={park.properties.ID}
latitude={park.geometry.coordinates[1]}
longitude={park.geometry.coordinates[0]}
>
<button
className="marker-btn"
onClick={e => {
e.preventDefault();
setSelectedPark(park);
}}
>
<img src={mapIcon} alt="Map Pointer Icon" />
</button>
</Marker>
))}
</ReactMapGL>
{selectedPark ? (
<div className={ styles.officeInfo }>
<div className={ styles.officeInfoImage }>
<img src={selectedPark.properties.IMAGE} />
</div>
<div className={ styles.officeInfoContent }>
<h3>{selectedPark.properties.NAME}</h3>
<p>{selectedPark.properties.DESCRIPTION}</p>
<button onClick={e => {
e.preventDefault();
setSelectedPark(null);
}}>X</button>
</div>
</div>
) : null}
</div>
);
}
代码演示 https://codesandbox.io/s/immutable-glitter-hokq6?file=/src/App.js
我会合法地请你喝一两杯咖啡来帮助你<3
最佳答案
在广泛使用 mapbox 之后,我可以告诉您 map.resize()
必须在某个时候调用,由您调用,或者由内部的 react-map-gl 绑定(bind)调用.
因此,您需要先创建一个调整大小处理程序,我更喜欢在钩子(Hook)中执行此操作:
const useResize = (handler) => {
useEffect(() => {
window.addEventListener("resize", handler);
return () => {
window.removeEventListener("resize", handler);
};
}, [handler]);
};
然后你可以在你的组件中使用它:
const onResize = useCallback(() => {
setViewport({ ...viewport });
}, []);
useResize(onResize);
由于您更新了视口(viewport)对象,react-map-gl 会将此识别为状态更改并相应地更新视口(viewport),可能是通过在内部调用 map.resize()
。
这是一个沙箱:https://codesandbox.io/s/upbeat-tdd-o8vn3?file=/src/App.js
另一个(可以说是更好的)解决方案 是简单地自己调用 map.resize()
。为此,只需在加载时捕获 map
对象:
<ReactMapGL
{...viewport}
onLoad={({ map }) => setMap(map)}
>
然后在调整大小处理程序中调用 map.resize()
:
const onResize = useCallback(() => {
if (map) {
map.resize();
}
}, [map]);
此解决方案将具有更好的性能,因为它更接近金属并且不需要克隆当前视口(viewport)对象。
这是此解决方案的沙箱:https://codesandbox.io/s/optimistic-kalam-8p8jo?file=/src/App.js
关于reactjs - 如何在更改浏览器宽度时调整 mapbox 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70352188/