index.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. "use client";
  2. import React, {useEffect, useRef} from 'react';
  3. import 'ol/ol.css';
  4. import Map from 'ol/Map';
  5. import View from 'ol/View';
  6. import TileLayer from 'ol/layer/Tile';
  7. import OSM from 'ol/source/OSM';
  8. import {fromLonLat} from 'ol/proj';
  9. const MapComponent = () => {
  10. const mapContainer = useRef(null);
  11. const mapInstance = useRef(null); // 保存地图实例
  12. useEffect(() => {
  13. if (!mapContainer.current) return;
  14. // 确保容器有明确的高度(修复100vh可能为0的问题)
  15. mapContainer.current.style.height = 'calc(100vh - 2px)'; // 减去边框宽度
  16. // 创建地图实例
  17. mapInstance.current = new Map({
  18. target: mapContainer.current,
  19. layers: [
  20. new TileLayer({
  21. source: new OSM()
  22. })
  23. ],
  24. view: new View({
  25. // 正确转换坐标到EPSG:3857
  26. center: fromLonLat([116.4074, 39.9042]),
  27. zoom: 4
  28. })
  29. });
  30. // 添加窗口大小变化监听
  31. const handleResize = () => {
  32. setTimeout(() => {
  33. if (mapInstance.current) {
  34. mapInstance.current.updateSize();
  35. }
  36. }, 100);
  37. };
  38. window.addEventListener('resize', handleResize);
  39. // 组件卸载时清理
  40. return () => {
  41. window.removeEventListener('resize', handleResize);
  42. if (mapInstance.current) {
  43. mapInstance.current.setTarget(null); // 解除地图与容器的绑定
  44. mapInstance.current = null;
  45. }
  46. };
  47. }, []);
  48. return (
  49. <div
  50. ref={mapContainer}
  51. style={{
  52. width: '100%',
  53. height: '100vh', // 保留100vh但添加安全计算
  54. border: '1px solid red',
  55. boxSizing: 'border-box' // 确保边框不增加额外尺寸
  56. }}
  57. />
  58. );
  59. };
  60. export default MapComponent;