2

Currently I'm trying to replicate this hover effect of this website on my map component: http://www.francoisrisoud.com/projects where basically when you hover over a dot, it brings up a full screen image and when you click on it, it'll take you to a particular page. Currently this is my React and CSS code:

export default function Map({posts}) {
    const [viewport, setViewport] = useState({
        latitude: 36.592206968562685,
        longitude: 3.332469343750031,
        width:"100%",
        height:"100vh",
        zoom: 1.3,
    });

    const [selectedProperty, setSelectedProperty] = useState(null)

  return (
      <div>
        <ReactMapGL {...viewport} mapboxApiAccessToken="//myAPIkey"
        mapStyle="mapbox://styles/jay/cks5xkaa892cp17o5hyxcuu0z"
        onViewportChange={viewport => {
            setViewport(viewport);
        }}>
        {
          posts &&
          posts.map((maps) => (
            <Marker key={maps.id} latitude={maps.Latitude} longitude={maps.Longitude}>
                {/* <div>{maps.Title}</div> */}
                <button className="marker-btn" onClick={e => {
                    e.preventDefault();
                    setSelectedProperty(maps);
                }}>
                    <img src="placeholder.svg"/>
                </button>
            </Marker>
          ))}

          {selectedProperty ? (
              <Popup latitude={selectedProperty.Latitude} longitude={selectedProperty.Longitude} 
              onClose={() => {setSelectedProperty(null);}}>
                <h1>{selectedProperty.Title}</h1>
              </Popup>) : null}
        </ReactMapGL> 
      </div>
    );
}

CSS:

.marker-btn{
  background: none;
  border: none;
  cursor: pointer;
}

.marker-btn :hover{
  background: #000;
  width: 100vw;
  height: 100vh;
  border: none;
  cursor: pointer;
}

.marker-btn img{
  width: 20px;
  height: 20px;
}

But when I hover over the Marker in my map this is the result I get:

enter image description here

I want it so that it covers my whole map and not just start from the point where I'm hovering. Additionally, if I hover out of it I want it to go away but when I drag my cursor towards the big popup, it doesnt go away.

JJM50
  • 467
  • 1
  • 7
  • 20

1 Answers1

2

There are a lot of ways to do it. Here is mine:

  1. Replace onClick prop and hover pseudo-class for the button inside the Marker component with onMouseEnter prop.
  2. Create your own Popup that has a full height and width of the parent component.
  3. Hide the Map component (by setting the width and height of viewport into 0%) and show the custom Popup component when the mouse enters the button and vice versa.

Here is the working code https://codesandbox.io/s/full-popup-mapbox-stackoverflow-36oi0?file=/src/App.js

Note: you have to attach your own Mapbox Token. You can get it from here https://account.mapbox.com/access-tokens/

import React, { useState } from "react";
import ReactMapGL, { Marker } from "react-map-gl";
import "./styles.css";

export default function App() {
  const [viewport, setViewport] = useState({
    latitude: 50.826758,
    longitude: 4.380197,
    width: "100vw",
    height: "100vh",
    zoom: 3
  });

  const YOURMAPBOXTOKEN = "";

  const posts = [
    {
      id: 1,
      latitude: 50.826758,
      longitude: 4.380197
    },
    {
      id: 2,
      latitude: 48.893615,
      longitude: 2.490906
    },
    {
      id: 3,
      latitude: 51.454007,
      longitude: -0.235523
    }
  ];

  const [selectedProperty, setSelectedProperty] = useState(null);
  const [isPopupShown, setIsPopupShown] = useState(false);

  return (
    <div className="root">
      {!isPopupShown && (
        <div className="map">
          <ReactMapGL
            {...viewport}
            mapboxApiAccessToken={YOURMAPBOXTOKEN}
            mapStyle="mapbox://styles/mapbox/dark-v9"
            onViewportChange={(viewport) => {
              setViewport(viewport);
            }}
          >
            {posts &&
              posts.map((item) => (
                <Marker
                  key={item.id}
                  latitude={item.latitude}
                  longitude={item.longitude}
                >
                  <button
                    className="marker-btn"
                    onMouseEnter={() => {
                      setSelectedProperty(item);
                      setViewport({
                        latitude: 50.826758,
                        longitude: 4.380197,
                        width: "0vw",
                        height: "0vh",
                        zoom: 3
                      });
                      setIsPopupShown(true);
                    }}
                  >
                    <img src="placeholder.svg" />
                  </button>
                </Marker>
              ))}
          </ReactMapGL>
        </div>
      )}

      {/* SHOW FULL CUSTOM POPUP HERE */}
      {selectedProperty && isPopupShown && (
        <div className="full-popup">
          // todo: create a closing popup button here
        </div>
      )}
    </div>
  );
}

Todo: you have to create a closing popup button for the custom Popup. You can do it by reversing my code like this:

  1. Set selectedProperty into null.
  2. Set isPopupShown into false.
  3. Sett the width and height of the viewport into 100%.
Jabal Logian
  • 1,666
  • 4
  • 24
  • 46