bbecquet / Leaflet.RotatedMarker

Leaflet plugin to enable the rotation of map marker icons
MIT License
258 stars 100 forks source link

setRotationAngle with react-leaflet #23

Open ziapk opened 5 years ago

ziapk commented 5 years ago

Hello!

I am using react-leaflet maps here are my marker code.

<Marker key={1} position={{ lat: position.latitude, lng: position.longitude }} rotationAngle={position.course} rotationOrigin="center" icon={L.icon({iconUrl: "xyz.svg", iconSize: [50,50], iconAnchor: [25, 25]})} />

position data update frequently but marker rotation didn't update after loading of map.

I don't know how to use setRotationAngle here.

please give me any example for way in react-leaflet

Thanks

kjellski commented 5 years ago

@ziapk this is due to a problem of 'react-leaflet' v2, which doesn't export exension methods of the classes anymore. See https://github.com/PaulLeCam/react-leaflet/issues/506

madchester commented 2 years ago

Hi @ziapk,

Try this, it's a bit of a hack I think, well the idea is to create a component using react-leaflet marker and set the angle for that marker.

I currently used this, been struggling integrating libraries using react-leaflet. Hope this helps

const RotateMarker = forwardRef(({ children, ...props }:any, forwardRef:any) => {
    const markerRef:any = useRef();

    const { rotationAngle, rotationOrigin } = props;
    useEffect(() => {
        const marker = markerRef.current;
        if (marker) {
            marker.setRotationAngle(rotationAngle);
            marker.setRotationOrigin(rotationOrigin);
        }
    }, [rotationAngle, rotationOrigin]);

    return (
        <Marker
            ref={(ref) => {
                markerRef.current = ref;
                if (forwardRef) {
                    forwardRef.current = ref;
                }
            }}
            {...props}
        >
            {children}
        </Marker>
    );
});
eugbyte commented 4 months ago

@madchester I modified your code to create a more type safe version for typescript. Additionally, install the npm package leaflet-rotatedmarker to extend the native Marker class with rotationAngle and rotationOrigin.

import { forwardRef, useEffect, useRef } from "react";
import { Marker, MarkerProps } from "react-leaflet";
import * as L from "leaflet";
import "leaflet-rotatedmarker"; // required to to add `rotationAngle ` and `rotationOrigin` to the Props of the native Marker component

type Props = MarkerProps & React.RefAttributes<L.Marker<any>>;

// see https://github.com/bbecquet/Leaflet.RotatedMarker/issues/23#issuecomment-1011836375
export const RotatableMarker = forwardRef(
  ({ children, ...props }: Props, forwardRef: React.ForwardedRef<any>) => {
    const markerRef = useRef<L.Marker>();

    const { rotationAngle, rotationOrigin } = props;
    useEffect(() => {
      if (markerRef.current == null) {
        return;
      }
      const marker: L.Marker = markerRef.current;
      marker.setRotationAngle(rotationAngle ?? 0);
      marker.setRotationOrigin(rotationOrigin ?? "center");
    }, [rotationAngle, rotationOrigin]);

    return (
      <Marker
        ref={(ref) => {
          markerRef.current = ref as L.Marker<any>;
          if (forwardRef != null) {
            (forwardRef as any).current = ref;
          }
        }}
        {...props}
      >
        {children}
      </Marker>
    );
  },
);

Then, call it as such:

        <RotatableMarker
          position={[position.latitude, position.longitude]}
          icon={
            new Icon({
              iconUrl: ",
            })
          }
          rotationOrigin={"center"}
          rotationAngle={position.heading ?? 0}
        />