[英]How to dynamically move and rotate marker in react-leaflet?
我用react-leaflet
和 hook 編寫了一個 React 項目。 我的目標是每秒移動和旋轉標記。 但是,移動部分工作正常。 但是標記的旋轉不起作用。 最近幾天我真的被困住了。 我找不到好的解決方案。 請幫我。
map 組件如下。
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.com/leaflet@1.0.3/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.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{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;
完整的問題在這個沙箱中: https://codesandbox.io/s/vigilant-wood-kgv4p?file=/src/App.js
在這篇文章中使用為旋轉標記提供的一些答案,能夠使其與您提供的代碼框一起使用。 默認的Marker
組件沒有rotationAngle
或rotationOrigin
作為有效的道具,您需要執行類似 done here的操作才能獲得它。 因此,我們可以使用重用輪換代碼並將其插入到您的代碼中,方法是將其提升為可重用的 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)`;
}
}
};
然后在使用useEffect
更改旋轉后調用它,因為我們還希望更新Markers
position 否則旋轉將不起作用:
useEffect(() => {
applyRotation(markerRef.current, { rotationAngle: heading + 5 });
}, [heading]);
當您調用myFunc
時,它會更新 position(緯度,經度)以及 header(旋轉),因此通過將其放置在 useEffect 中,下一次渲染Marker
應該更新其 Z4757FE07FD492A8BE0EA6A760EDD
我在這里有一個代碼框示例。
上述解決方案確實存在一些問題,您需要篩選leaflet-rotatedmarker
庫以獲取那些丟失的邊緣情況。 但是,如果您可以添加該庫,則更好的解決方案是導入:
import L from "leaflet";
import "leaflet-rotatedmarker";
並改用擴展的setRotationAngle
。
useEffect(() => {
if (markerRef.current) {
markerRef.current.setRotationAngle(heading);
}
}, [heading]);
您還可以使用它來將其提升到RotatedMarker
組件中,以便您原來的 props rotationAngle={heading} rotationOrigin="center"
用例可以工作:
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>
);
});
這是我測試上述內容的代碼筆
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.