javascript - React Leaflet - Align Popup on the center of the map - Stack Overflow

If I click on a marker I want to pan the map view to the center of the marker. So far this works on my

If I click on a marker I want to pan the map view to the center of the marker. So far this works on my project. Furthermore I want the opened popup to be aligned on the center of the map view.

I thought I could hard-code this with the leaflet-popup class like so:

.leaflet-popup {
  transform: translate(-40%, 50%) !important;
}

But this does not work. The Problem with my code is, that the popup is positioned independently of the map view. But it should be centered according to the current view. I can show you my map setup:

EDIT

I provided a CodeSandBox link to play around. Click On the Marker on the top and you'll see that the popup is not aligned on the center of the screen:

Map Component

const {Map, TileLayer, Marker, GeoJSON} = ReactLeaflet;

function MapOverlay({setSwipeState}) {
    const mapRef = useRef(null);
    const [donationLocations] = useState([
        [48.135125, 11.581981], [58.403, 20.420], [43.300, 40],
        [70.505, -20], [40.505, -80], [-40.505, -10]
    ]);


    function centerMapView(e) {
        const {leafletElement} = mapRef.current;

        if(e) {
            leafletElement.setView(e.popup._latlng); // center view to where popup opens
            // todo: align popup in the middle of the screen
            // Get bounds of map view, divide it by 2 and apply coorditanes to the popup position


        }

    }

    function getMapData() {
        return (
            <div>
                {
                    donationLocations.map((position, i) =>
                        (
                            <Marker position={position} key={i}>
                                <MarkerPopup/>
                            </Marker>
                        )
                    )
                }
            </div>
        )
    }

    return (
        <Map
            ref={mapRef}
            center={[45.000, 10.000]}
            zoom={3}
            onPopupopen={centerMapView.bind(this)}
            zoomControl={false}
            minZoom={3}
            bounceAtZoomLimits={true}
            maxBoundsViscosity={.95}
            maxBounds={[[-180, -90], [180, 90]]}
        >
            <TileLayer
                noWrap={true}
                attribution='&amp;copy <a href="">OpenStreetMap</a> contributors | &amp;copy <a href="/">Mapbox</a>'
                url={'/{z}/{x}/{y}?access_token=' + process.env.REACT_APP_MAPBOX_KEY}
            />
            {getMapData()}
        </Map>
    )
}

Marker-Popup Component

const {Popup} = ReactLeaflet;

export default function MarkerPopup() {

    return (
        <Popup
            autoPan={false} // Important part here
        >
            <Card>
                   ...
            </Card>
        </Popup>
    );
}

If I click on a marker I want to pan the map view to the center of the marker. So far this works on my project. Furthermore I want the opened popup to be aligned on the center of the map view.

I thought I could hard-code this with the leaflet-popup class like so:

.leaflet-popup {
  transform: translate(-40%, 50%) !important;
}

But this does not work. The Problem with my code is, that the popup is positioned independently of the map view. But it should be centered according to the current view. I can show you my map setup:

EDIT

I provided a CodeSandBox link to play around. Click On the Marker on the top and you'll see that the popup is not aligned on the center of the screen:

Map Component

const {Map, TileLayer, Marker, GeoJSON} = ReactLeaflet;

function MapOverlay({setSwipeState}) {
    const mapRef = useRef(null);
    const [donationLocations] = useState([
        [48.135125, 11.581981], [58.403, 20.420], [43.300, 40],
        [70.505, -20], [40.505, -80], [-40.505, -10]
    ]);


    function centerMapView(e) {
        const {leafletElement} = mapRef.current;

        if(e) {
            leafletElement.setView(e.popup._latlng); // center view to where popup opens
            // todo: align popup in the middle of the screen
            // Get bounds of map view, divide it by 2 and apply coorditanes to the popup position


        }

    }

    function getMapData() {
        return (
            <div>
                {
                    donationLocations.map((position, i) =>
                        (
                            <Marker position={position} key={i}>
                                <MarkerPopup/>
                            </Marker>
                        )
                    )
                }
            </div>
        )
    }

    return (
        <Map
            ref={mapRef}
            center={[45.000, 10.000]}
            zoom={3}
            onPopupopen={centerMapView.bind(this)}
            zoomControl={false}
            minZoom={3}
            bounceAtZoomLimits={true}
            maxBoundsViscosity={.95}
            maxBounds={[[-180, -90], [180, 90]]}
        >
            <TileLayer
                noWrap={true}
                attribution='&amp;copy <a href="http://osm/copyright">OpenStreetMap</a> contributors | &amp;copy <a href="https://apps.mapbox./feedback/">Mapbox</a>'
                url={'https://api.mapbox./styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token=' + process.env.REACT_APP_MAPBOX_KEY}
            />
            {getMapData()}
        </Map>
    )
}

Marker-Popup Component

const {Popup} = ReactLeaflet;

export default function MarkerPopup() {

    return (
        <Popup
            autoPan={false} // Important part here
        >
            <Card>
                   ...
            </Card>
        </Popup>
    );
}
Share edited Nov 22, 2019 at 15:52 MarcoLe asked Nov 19, 2019 at 15:55 MarcoLeMarcoLe 2,5397 gold badges41 silver badges80 bronze badges 2
  • Hello. Is this what you have so far? If that is the case you center the marker on its y axis let's say rather than in the center of the map and the popup looks ok, centered as well. What exactly do you want to achieve? – kboul Commented Nov 22, 2019 at 8:37
  • @kboul I updated my question with a CodeSandBox link. What I want to achieve is a popup perfectly aligned on the center of the map. Greetings Marco – MarcoLe Commented Nov 22, 2019 at 11:35
Add a ment  | 

3 Answers 3

Reset to default 4

I managed to get it working. The Solution was to make a modal dialog that is detached from the DOM.

You can see the working code: Here

// Pass open state an setOpen function from the parent
function MarkerPopup({open, setOpen}) {
  const classes = useStyles();

  function handleClose() {
      setOpen(false);
  }

  return (
      <Popup
          autoPan={false}
      >
          <Modal
              className={classes.modal}
              open={open}
              classes={{root: classes.root}}
              onClose={handleClose.bind(this)}
              BackdropComponent={Backdrop}
              BackdropProps={{
                  timeout: 0,
                  invisible: true
              }}
          >
              <Card className={classes.card}>
                  <CardMedia
                      className={classes.media}
                      image="https://material-ui./static/images/cards/contemplative-reptile.jpg"
                      title="Contemplative Reptile"
                  />
                  <CardContent>
                      <Typography gutterBottom variant="h5" ponent="h2">
                          Lizard
                      </Typography>
                      <Typography variant="body2" color="textSecondary" ponent="p">
                          Lizards are a widespread group of squamate reptiles, with over 6,000 species, ranging
                          across all continents except Antarctica
                      </Typography>
                  </CardContent>
                  <CardActions>
                      <Button size="small" color="primary">
                          Details
                      </Button>
                      <Button size="small" color="primary">
                          Donate
                      </Button>
                  </CardActions>
              </Card>
          </Modal>
      </Popup>
  );
}
function centerMapView(e) {
  const { leafletElement } = mapRef.current;
  if (e) {
    const popupLatlng = e.popup._latlng;
    const zoom = leafletElement.getZoom();
    const point = leafletElement.project(popupLatlng, zoom);
    const newPoint = point.subtract([0, 180]);
    const newLatlng = leafletElement.unproject(newPoint, zoom);
    leafletElement.panTo(newLatlng, { animate: true });
  }
}

You can update your centerMapView function to the following. This will first convert your Latlng value into a point value, then modify the value by subtracting a specific amount of pixels ( offset ), finally converting the point value back to Latlng and call panTo with the value.

Best solution would be to make a modal popup that is always in the center of the screen.

Display it on the event on('popupopen')

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744913410a4600686.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信