admin管理员组文章数量:1394183
I have wrote a React project with react-leaflet
and hook. My goal is to move and rotate marker every second. However, moving part is working fine. But the rotation of marker is not working. I am really stuck for last few days. I couldn't find a good solution. Please help me.
The map ponent is as follows.
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import { useState, useEffect } from "react";
import L from 'leaflet';
import 'leaflet-marker-rotation';
const MySimpleMap = () => {
const [lat, setLat] = useState(22.899397);
const [lon, setLon] = useState(89.508279);
const [heading, setHeading] = useState(30)
useEffect(() => {
const interval = setInterval(() => {
myfun();
}, 1000);
return () => {
clearInterval(interval);
};
}, [lat]);
const defaultIcon = L.icon({
iconUrl: "/[email protected]/dist/images/marker-icon.png",
iconSize: [20, 40],
iconAnchor: [18, 18],
popupAnchor: [0, -10],
shadowAnchor: [10, 10]
});
const myfun = () => {
setLat(lat + 0.00001);
setLon(lon + 0.00001);
setHeading(heading+5);
console.log("angle:" + heading);
};
return (
<MapContainer className="map" center={[lat, lon]} zoom={21}>
<TileLayer
attribution='&copy <a href=";>OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap/{z}/{x}/{y}.png"
/>
<Marker position={[lat, lon]} icon={defaultIcon} rotationAngle={heading} rotationOrigin="center">
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
);
};
export default MySimpleMap;
The plete problem is in this sandbox: =/src/App.js
I have wrote a React project with react-leaflet
and hook. My goal is to move and rotate marker every second. However, moving part is working fine. But the rotation of marker is not working. I am really stuck for last few days. I couldn't find a good solution. Please help me.
The map ponent is as follows.
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import { useState, useEffect } from "react";
import L from 'leaflet';
import 'leaflet-marker-rotation';
const MySimpleMap = () => {
const [lat, setLat] = useState(22.899397);
const [lon, setLon] = useState(89.508279);
const [heading, setHeading] = useState(30)
useEffect(() => {
const interval = setInterval(() => {
myfun();
}, 1000);
return () => {
clearInterval(interval);
};
}, [lat]);
const defaultIcon = L.icon({
iconUrl: "https://unpkg./[email protected]/dist/images/marker-icon.png",
iconSize: [20, 40],
iconAnchor: [18, 18],
popupAnchor: [0, -10],
shadowAnchor: [10, 10]
});
const myfun = () => {
setLat(lat + 0.00001);
setLon(lon + 0.00001);
setHeading(heading+5);
console.log("angle:" + heading);
};
return (
<MapContainer className="map" center={[lat, lon]} zoom={21}>
<TileLayer
attribution='&copy <a href="http://osm/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap/{z}/{x}/{y}.png"
/>
<Marker position={[lat, lon]} icon={defaultIcon} rotationAngle={heading} rotationOrigin="center">
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
);
};
export default MySimpleMap;
The plete problem is in this sandbox: https://codesandbox.io/s/vigilant-wood-kgv4p?file=/src/App.js
Share Improve this question edited Feb 23, 2021 at 23:01 manjurul Islam asked Feb 23, 2021 at 22:43 manjurul Islammanjurul Islam 731 silver badge8 bronze badges 1- I have also created a sandbox here: codesandbox.io/s/vigilant-wood-kgv4p?file=/src/App.js – manjurul Islam Commented Feb 23, 2021 at 23:00
2 Answers
Reset to default 4Using some of the provided answers for rotating markers in this post , was able to get it to work with your provided codesandbox. The default Marker
ponent does not have rotationAngle
or rotationOrigin
as valid props, you'd need to do something like done here to get that. So instead we can use re-use the rotation code and plug it into your code by lifting it into a re-usable function:
const applyRotation = (marker, _options) => {
const oldIE = L.DomUtil.TRANSFORM === "msTransform";
const options = Object.assign(_options, { rotationOrigin: "center" });
const { rotationAngle, rotationOrigin } = options;
if (rotationAngle && marker) {
marker._icon.style[L.DomUtil.TRANSFORM + "Origin"] = rotationOrigin;
if (oldIE) {
// for IE 9, use the 2D rotation
marker._icon.style[L.DomUtil.TRANSFORM] = `rotate(${rotationAngle} deg)`;
} else {
// for modern browsers, prefer the 3D accelerated version
marker._icon.style[
L.DomUtil.TRANSFORM
] += ` rotateZ(${rotationAngle}deg)`;
}
}
};
And then calling it once the rotation has been changed with a useEffect
because we also want the Markers
position to be updated otherwise the rotation won't work:
useEffect(() => {
applyRotation(markerRef.current, { rotationAngle: heading + 5 });
}, [heading]);
When you call myFunc
it updates the position (lat,lon) as well as the header (rotation) so by placing it in the useEffect, on next render Marker
should have updated its position.
I have a codebox example here.
The above solution does have some issue's you'll need to sift through the leaflet-rotatedmarker
library to get those missing edge cases. However if you can add that library a better solution would be importing that:
import L from "leaflet";
import "leaflet-rotatedmarker";
and using the extended setRotationAngle
instead.
useEffect(() => {
if (markerRef.current) {
markerRef.current.setRotationAngle(heading);
}
}, [heading]);
You can also use that to lift it into a RotatedMarker
ponent so that your original use case of the props rotationAngle={heading} rotationOrigin="center"
will work:
const RotatedMarker = forwardRef(({ children, ...props }, forwardRef) => {
const markerRef = 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>
);
});
Here's the codepen where i tested the above out
To live rotate the marker when the rotation angle changes you must update the rotation value using the marker's refrence, you can update your code as follow:
/* your other code */
const markerRef = useRef(null)
useEffect(()=>{
if(markerRef.current)
{ markerRef.current.setRotationAngle(heading); }
},[heading])
.....
....
<Marker ref={markerRef} rotationAngle={heading}>
...other code
</Marker>
本文标签: javascriptHow to dynamically move and rotate marker in reactleafletStack Overflow
版权声明:本文标题:javascript - How to dynamically move and rotate marker in react-leaflet? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744765525a2624015.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论