holytrips / react-leaflet-marker

To use React components as map markers with react-leaflet
https://holytrips.github.io/react-leaflet-marker/
MIT License
12 stars 4 forks source link

Multiple markers have a vertical offset in pixels as the accumulation of height of the previous siblings #9

Open Lamap opened 1 year ago

Lamap commented 1 year ago

The title pretty much explains the issue I experience. If I am using a position absolute and adjusting the top position within the custom react node by the accumulated offset, it solves the issue. I wonder if is there any trivial that I am missing? I am using the tool with this versions: "react-leaflet": "^4.2.0", "react-leaflet-marker": "^2.1.0", And also having a stylesheet for leaflet as direct link: <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin=""/>.

Thank you for any advise or confirmation in advance.

eug-vs commented 1 year ago

Also having this issue, @Lamap did you manage to find the workaround or working version?

eug-vs commented 1 year ago

Oh sorry I'm blind, as you said position: absolute fixes the issue for me. I didn't even have to update top position, it just works now, which is strange if it wasn't enough for you

eug-vs commented 1 year ago

I found that even with position absolute, if you provide sizes it immediately breaks (to the same behavior as described in the issue). Also position absolute breaks z-index - so riseOnHover doesn't work anymore (it works, but z-index is ignored on absolute element).

Lamap commented 1 year ago

I found that even with position absolute, if you provide sizes it immediately breaks (to the same behavior as described in the issue). Also position absolute breaks z-index - so riseOnHover doesn't work anymore (it works, but z-index is ignored on absolute element).

@eug-vs Thank you for your feedback! It confirms to me that indeed there is some issue even if it is not the exact same that I experience. FYI for me it works only with the vertical 'top' adjustment, does not matter if I use the size prop on the Marker or not. The reason behind the different behavours must be the different lib versions we use.

eug-vs commented 1 year ago

I've tried using the same versions as you mentioned and the issue is present. Could you share the snippet how exactly are you doing the top adjustment? Here's my example, I didn't strip out anything in case it could matter.

<MapContainer
  center={[rentals[0]?.location.coordinates[1], rentals[0]?.location.coordinates[0]] as LatLngExpression}
  dragging={true}
  touchZoom={true}
  doubleClickZoom={true}
  zoom={13}
  ref={mapRef}
  className={`w-full h-96 md:h-[800px] z-0 relative ${className}`}
>
  <MarkerLayer>
    {rentals.map(rental => (
      <Marker
        position={[rental.location.coordinates[1], rental.location.coordinates[0]] as LatLngExpression}
        key={rental.id}
        riseOffset={250} // TODO: fix after https://github.com/holytrips/react-leaflet-marker/issues/9
        zIndexOffset={0}
        placement="center"
        interactive
        riseOnHover
      >
        <Link href={`/rentals/${rental.id}`} className="w-12 h-12 absolute bg-white rounded-full" title={rental.title}>
          <Image src={rental.imageUrls[0] || ''} alt={rental.title} fill className="rounded-full ring-slate-700 hover:ring-slate-50 ring-2 shadow-md shadow-slate-800" />
        </Link>
      </Marker>
    ))}
  </MarkerLayer>
  <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
</MapContainer>

Do you have any other elements with position: absolute inside MapContainer? I think the behavior slighlty changed when I removed my custom absolute button which was inside MapContainer.

Lamap commented 1 year ago

Sure thing. This is just a messy code where I played, what for I appologise but had no time to clean it up. I used the react-leaflet-marker as MarkerExtra and also used overlays, but it does not make any difference for me. `import '../../node_modules/leaflet/dist/leaflet.css'; import React from 'react'; import { useParams } from 'react-router-dom'; import { MapContainer, TileLayer, Marker } from 'react-leaflet'; import { Marker as MarkerExtra, MarkerLayer } from 'react-leaflet-marker'; import L from 'leaflet'; import myIcon from '../map-marker-area.svg';

export function Page2(): React.ReactElement { const { id } = useParams(); const markers: { lat: number; lng: number }[] = [ { lat: 47.25, lng: 19.25 }, { lat: 47.23, lng: 19.21 }, { lat: 47.27, lng: 19.27 }, { lat: 47.22, lng: 19.22 }, { lat: 47.21, lng: 19.29 }, { lat: 47.21, lng: 19.21 }, { lat: 47.28, lng: 19.2 }, ]; const iconPerson: L.Icon = new L.Icon({ iconUrl: myIcon, iconSize: new L.Point(40, 40), });

return (
    <div>
        page2 {id}
        <MapContainer center={{ lat: 47.8, lng: 19.9 }} style={{ background: '#ff0000', height: '500px', width: '700px' }} zoom={10}>
            <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
            <Marker position={{ lat: 48, lng: 20.7 }} icon={iconPerson}></Marker>
            <Marker position={{ lat: 48.4, lng: 20.5 }} draggable icon={iconPerson}></Marker>

            <MarkerLayer>
                <>
                    <MarkerExtra position={{ lat: 47, lng: 19.5 }} interactive={true} placement={'center'} size={[30, 30]}>
                        <div
                            style={{
                                background: '#000000',
                                cursor: 'pointer',
                                width: '30px',
                                height: '30px',
                                position: 'absolute',
                                top: '0',
                            }}
                        ></div>
                    </MarkerExtra>
                    <MarkerExtra position={{ lat: 47, lng: 19 }} interactive={true} placement={'center'} size={[30, 30]}>
                        <button
                            style={{
                                background: '#ff00ff',
                                cursor: 'pointer',
                                width: '30px',
                                height: '30px',
                                border: 'none',
                                position: 'absolute',
                                top: '-30px',
                            }}
                            onClick={(): void => console.log('sss')}
                        ></button>
                    </MarkerExtra>

                    <MarkerExtra position={{ lat: 47.5, lng: 19.5 }} interactive={true} placement={'center'} size={[30, 30]}>
                        <div
                            style={{
                                background: '#ff0000',
                                cursor: 'pointer',
                                width: '30px',
                                height: '30px',
                                position: 'absolute',
                                top: '-60px',
                            }}
                        ></div>
                    </MarkerExtra>
                    <MarkerExtra position={{ lat: 47.5, lng: 19 }} interactive={true} placement={'center'} size={[30, 30]}>
                        <div
                            style={{
                                background: '#ffff00',
                                cursor: 'pointer',
                                width: '30px',
                                height: '30px',
                                position: 'absolute',
                                top: '-90px',
                            }}
                        ></div>
                    </MarkerExtra>
                </>

                {markers.map((c, index) => (
                    <MarkerExtra key={`${index}-${c.lat}-${c.lng}`} position={[c.lat, c.lng]} size={[30, 30]} zIndexOffset={0}>
                        <button
                            style={{
                                background: '#ff0000',
                                borderRadius: '50%',
                                cursor: 'pointer',
                                position: 'absolute',
                                top: `-${index * 30 + 90}px`,
                            }}
                            onClick={(): void => console.log('sss')}
                        >
                            D
                        </button>
                    </MarkerExtra>
                ))}
            </MarkerLayer>
        </MapContainer>
    </div>
);

} `

Lamap commented 1 year ago

Maybe my react version matters as well: "react": "^18.2.0",

eug-vs commented 1 year ago

I use the same react version. Thanks for sharing, maybe this will be helpful if someone else gives this a look. I couldn't find anything that can give us a hint

Also you accidentally pasted your firebase token, so make sure to revoke it asap, be careful with such things

Lamap commented 1 year ago

Opss, thy! I didn't notice that is included in the url :/

Lamap commented 1 year ago

FYI, when I wrapped the Marker inside a component it needed only the position: absolute to make it work.