Files
TJWaterFrontend_Refine/src/app/OlMap/Controls/Zoom.tsx
2025-09-28 15:51:45 +08:00

105 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from "react";
import { useMap } from "../MapComponent";
import Geolocation from "ol/Geolocation";
import AddRoundedIcon from "@mui/icons-material/AddRounded";
import RemoveRoundedIcon from "@mui/icons-material/RemoveRounded";
import GpsFixedRoundedIcon from "@mui/icons-material/GpsFixedRounded";
import clsx from "clsx";
const INITIAL_ZOOM = 14; // 默认缩放级别
const Zoom: React.FC = () => {
const map = useMap();
const [locateDisabled, setLocateDisabled] = useState(false);
// 放大函数
const handleZoomIn = () => {
if (!map) return;
const view = map.getView();
view.animate({ zoom: (view.getZoom() ?? 0) + 1, duration: 200 });
};
// 缩小函数
const handleZoomOut = () => {
if (!map) return;
const view = map.getView();
view.animate({ zoom: (view.getZoom() ?? 0) - 1, duration: 200 });
};
// 定位功能
const handleLocate = () => {
if (!map) return;
const geolocation = new Geolocation({
trackingOptions: { enableHighAccuracy: true },
projection: map.getView().getProjection(),
});
geolocation.once("change:position", () => {
const coords = geolocation.getPosition();
if (coords) {
map
.getView()
.animate({ center: coords, zoom: INITIAL_ZOOM, duration: 500 });
}
geolocation.setTracking(false);
});
geolocation.setTracking(true);
};
// 包装 handleLocate点击后禁用按钮一段时间
const onLocateClick = () => {
navigator.geolocation.getCurrentPosition(
() => {
handleLocate();
},
(error) => {
console.log(error.message);
setLocateDisabled(true); // 定位失败后禁用按钮
// alert("定位失败,将使用默认位置。");
}
);
};
return (
<div className="absolute right-4 bottom-8">
<div className="w-8 h-26 flex flex-col gap-2 items-center">
<div
className={clsx(
"w-8 h-8 bg-gray-50 flex items-center justify-center rounded-xl drop-shadow-xl shadow-black",
locateDisabled && "text-gray-300"
)}
>
<button
className="w-6 h-6 flex items-center justify-center rounded-xl hover:bg-white transition-all duration-100"
onClick={onLocateClick}
disabled={locateDisabled}
>
<GpsFixedRoundedIcon fontSize="small" />
</button>
</div>
<div className="w-8 h-16 flex flex-col items-center justify-center bg-gray-50 rounded-xl drop-shadow-xl shadow-black">
<button
className="w-6 h-6 flex items-center justify-center rounded-xl hover:bg-white transition-all duration-100"
onClick={handleZoomIn}
aria-label="放大"
>
<AddRoundedIcon />
</button>
<div className="m-0.5 border-t-1 border-gray-300 w-6"></div>
<button
className="w-6 h-6 flex items-center justify-center rounded-xl hover:bg-white transition-all duration-100"
onClick={handleZoomOut}
aria-label="缩小"
>
<RemoveRoundedIcon />
</button>
</div>
</div>
</div>
);
};
export default Zoom;