0

I try to find a way to adjust markers popup window position based on following condition: if popup is near map containers edge.

Reason: right now popup is being hidden under container if marker (and popup, ofc) is near edge.

Working example: I am not sure do I have rights to link you to a different website except sandboxes, but Zillow popups does everything I've described - popup adjust position a bit to the left if initial position is going to be under the right edge of container (accept this for each edge of container)

Simple approaches: tried to add zIndex to popup component to place popup on top of container, but it doesn't work 'cause of GoogleMap's canvas

My Markers component clusterer render function:

  const renderClusterer = (clusterer, locations): any => {
    return (
      <OverlayViewF
        mapPaneName={'overlayMouseTarget'}
        position={{ lat: 0, lng: 0 }}
      >
        {locations?.map((location: IEstate, index) => (
          <OverlayViewF
            zIndex={999999}
            key={location.id}
            mapPaneName={'overlayMouseTarget'}
            position={{ lat: location.latitude, lng: location.longitude }}
          >
            <MarkerF
              position={{ lat: location.latitude, lng: location.longitude }}
              icon={{
                url: getMarkerIcon(location.isViewed, location.isFavorite),
                scaledSize: new window.google.maps.Size(17, 17),
              }}
              onClick={(e) => navigate(`/estate/${location.id}`)}
              onMouseOver={(e) => {
                setTooltip(location)
                globalStore.setHoveredEstateId(location.id)
              }}
              onMouseOut={(e) => {
                setTooltip(null)
                globalStore.setHoveredEstateId(null)
              }}
              clusterer={clusterer}
            >
            </MarkerF>
          </OverlayViewF>
        ))}
        {tooltip && tooltip.id && <StyledPopup marker={tooltip} />}
      </OverlayViewF>
    )
  }

Actual implementation in the component jsx body:

return (
  locations?.length > 0 && (
      <MarkerClustererF
        gridSize={11}
        minimumClusterSize={10}
        options={{
          enableRetinaIcons: true,
        }}
      >
        {(clusterer) => renderClusterer(clusterer, locations)}
      </MarkerClustererF>
    )
)

StyledPopup component jsx body:

<OverlayViewF
  mapPaneName={'overlayMouseTarget'}
  position={{ lat: marker.latitude, lng: marker.longitude }}
>
  //...regular jsx here, does nothing with @react-google-maps/api
</OverlayViewF>

UPD:

Tried to use following function to calculate adjustments:

  const adjustPopupPosition = useCallback(
    (position) => {
      const mapContainer = mapRef.current
      if (!mapContainer) return position
      console.log(!!mapContainer, mapContainer)

      const mapContainerRect = mapContainer.getBoundingClientRect()
      const popupWidth = 400

      const maxRightPosition = mapContainerRect.width - popupWidth
      const maxBottomPosition = mapContainerRect.height

      const adjustedPosition = {
        x: Math.min(position.x, maxRightPosition),
        y: Math.min(position.y, maxBottomPosition),
      }

      return adjustedPosition
    },
    [mapRef],
  )

And then used it in my StyledPopup like this:

  <OverlayViewF
    mapPaneName={'overlayMouseTarget'}
    position={{ lat: adjustedPosition.x, lng: adjustedPosition.y }}
  >
    //rest of regular jsx
  </OverlayViewF>

But still no results. Popup width is 400px.

0 Answers0