如何解决如何在 react-leaflet 中动态移动和旋转标记?
我用 react-leaflet
和 hook 编写了一个 React 项目。我的目标是每秒移动和旋转标记。但是,移动部件工作正常。但是标记的旋转不起作用。最近几天我真的被困住了。我找不到好的解决方案。请帮帮我。
地图组件如下。
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
解决方法
在此 post 中使用一些提供的旋转标记答案,能够使其与您提供的代码和框一起使用。默认的 Marker
组件没有 rotationAngle
或 rotationOrigin
作为有效道具,您需要执行诸如 done here 之类的操作才能获得它。因此,我们可以重用旋转代码,并将其提升为可重用的函数,从而将其插入到您的代码中:
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
位置,否则旋转将不起作用:
useEffect(() => {
applyRotation(markerRef.current,{ rotationAngle: heading + 5 });
},[heading]);
当您调用 myFunc
时,它会更新位置 (lat,lon) 以及标题(旋转),因此通过将其放置在 useEffect 中,在下一次渲染时 Marker
应该更新其位置。
我有一个代码框示例 here。
上述解决方案确实存在一些问题,您需要筛选 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>
);
});
这是我测试 above out 的代码笔
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。