89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import React, { useEffect, useState, useRef } from "react";
|
|
import { useMap } from "../MapComponent";
|
|
import { ScaleLine } from "ol/control";
|
|
|
|
const Scale: React.FC = () => {
|
|
const map = useMap();
|
|
const [zoomLevel, setZoomLevel] = useState(0);
|
|
const [coordinates, setCoordinates] = useState<[number, number]>([0, 0]);
|
|
const scaleLineRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
if (!map) return;
|
|
|
|
const updateZoomLevel = () => {
|
|
const zoom = map.getView().getZoom();
|
|
setZoomLevel(zoom ?? 0); // 如果 zoom 是 undefined,则使用默认值 0
|
|
};
|
|
|
|
const updateCoordinates = (event: any) => {
|
|
const coords = event.coordinate;
|
|
const transformedCoords = coords.map((c: number) =>
|
|
parseFloat(c.toFixed(4))
|
|
);
|
|
setCoordinates(transformedCoords);
|
|
};
|
|
|
|
map.on("moveend", updateZoomLevel);
|
|
map.on("pointermove", updateCoordinates);
|
|
|
|
// Initialize values
|
|
updateZoomLevel();
|
|
|
|
// ScaleLine control
|
|
const scaleControl = new ScaleLine({
|
|
target: scaleLineRef.current || undefined,
|
|
units: "metric",
|
|
bar: false,
|
|
steps: 4,
|
|
text: true,
|
|
minWidth: 64,
|
|
});
|
|
map.addControl(scaleControl);
|
|
|
|
return () => {
|
|
map.un("moveend", updateZoomLevel);
|
|
map.un("pointermove", updateCoordinates);
|
|
map.removeControl(scaleControl);
|
|
};
|
|
}, [map]);
|
|
|
|
return (
|
|
<>
|
|
<style>
|
|
{`
|
|
.custom-scale-line .ol-scale-line {
|
|
position: static;
|
|
background: transparent;
|
|
padding: 0;
|
|
}
|
|
.custom-scale-line .ol-scale-line-inner {
|
|
border: 1px solid #475569;
|
|
border-top: none;
|
|
color: #334155;
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
transition: all 0.3s;
|
|
}
|
|
`}
|
|
</style>
|
|
<div className="absolute bottom-0 right-0 flex items-center gap-2 px-3 py-1.5 bg-white/90 hover:bg-white rounded-tl-xl shadow-lg backdrop-blur-sm text-xs font-medium text-slate-700 z-1300 transition-all duration-300 pointer-events-auto">
|
|
<div
|
|
ref={scaleLineRef}
|
|
className="custom-scale-line flex items-center justify-center min-w-[60px]"
|
|
/>
|
|
<div className="h-3 w-px bg-slate-300 mx-1" />
|
|
<div className="min-w-[60px] text-center">
|
|
缩放: {zoomLevel.toFixed(1)}
|
|
</div>
|
|
<div className="h-3 w-px bg-slate-300 mx-1" />
|
|
<div className="tabular-nums min-w-[140px] text-center">
|
|
坐标: {coordinates[0]}, {coordinates[1]}
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Scale;
|