improve UX of "show attributes" mode

This commit is contained in:
kajkal
2023-03-26 12:43:04 +02:00
parent 0dbe87cfdd
commit e21d1b5c76

View File

@@ -128,7 +128,18 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
"source-layer": layer.id, "source-layer": layer.id,
paint: { paint: {
"fill-color": schemeSet3[i % 12], "fill-color": schemeSet3[i % 12],
"fill-opacity": 0.2, "fill-opacity": [
"case",
["boolean", ["feature-state", "hover"], false],
0.35,
0.2,
],
"fill-outline-color": [
"case",
["boolean", ["feature-state", "hover"], false],
"hsl(0,100%,90%)",
"rgba(0,0,0,0)",
],
}, },
filter: ["==", ["geometry-type"], "Polygon"], filter: ["==", ["geometry-type"], "Polygon"],
}); });
@@ -139,7 +150,12 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
"source-layer": layer.id, "source-layer": layer.id,
paint: { paint: {
"line-color": schemeSet3[i % 12], "line-color": schemeSet3[i % 12],
"line-width": 0.5, "line-width": [
"case",
["boolean", ["feature-state", "hover"], false],
2,
0.5,
],
}, },
filter: ["==", ["geometry-type"], "LineString"], filter: ["==", ["geometry-type"], "LineString"],
}); });
@@ -150,6 +166,12 @@ const vectorStyle = async (file: PMTiles): Promise<any> => {
"source-layer": layer.id, "source-layer": layer.id,
paint: { paint: {
"circle-color": schemeSet3[i % 12], "circle-color": schemeSet3[i % 12],
"circle-radius": [
"case",
["boolean", ["feature-state", "hover"], false],
6,
5,
],
}, },
filter: ["==", ["geometry-type"], "Point"], filter: ["==", ["geometry-type"], "Point"],
}); });
@@ -195,12 +217,13 @@ function MaplibreMap(props: { file: PMTiles }) {
let [showAttributes, setShowAttributes] = useState<boolean>(false); let [showAttributes, setShowAttributes] = useState<boolean>(false);
let [showTileBoundaries, setShowTileBoundaries] = useState<boolean>(false); let [showTileBoundaries, setShowTileBoundaries] = useState<boolean>(false);
const mapRef = useRef<maplibregl.Map | null>(null); const mapRef = useRef<maplibregl.Map | null>(null);
const hoveredFeaturesRef = useRef<Set<MapGeoJSONFeature>>(new Set());
// make it accessible in hook // make it accessible in hook
const showAttributesRef = useRef(showAttributes); const showAttributesRef = useRef(showAttributes);
useEffect(() => { useEffect(() => {
showAttributesRef.current = showAttributes; showAttributesRef.current = showAttributes;
}); }, [showAttributes]);
const toggleHamburger = () => { const toggleHamburger = () => {
setHamburgerOpen(!hamburgerOpen); setHamburgerOpen(!hamburgerOpen);
@@ -208,6 +231,7 @@ function MaplibreMap(props: { file: PMTiles }) {
const toggleShowAttributes = () => { const toggleShowAttributes = () => {
setShowAttributes(!showAttributes); setShowAttributes(!showAttributes);
mapRef.current!.getCanvas().style.cursor = !showAttributes ? "crosshair" : "";
}; };
const toggleShowTileBoundaries = () => { const toggleShowTileBoundaries = () => {
@@ -242,18 +266,28 @@ function MaplibreMap(props: { file: PMTiles }) {
mapRef.current = map; mapRef.current = map;
map.on("mousemove", (e) => { map.on("mousemove", (e) => {
const hoveredFeatures = hoveredFeaturesRef.current;
for (const feature of hoveredFeatures) {
map.setFeatureState(feature, {hover: false});
hoveredFeatures.delete(feature);
}
if (!showAttributesRef.current) { if (!showAttributesRef.current) {
popup.remove(); popup.remove();
return; return;
} }
var bbox = e.point;
var features = map.queryRenderedFeatures(bbox); const {x, y} = e.point;
const r = 2; // radius around the point
var features = map.queryRenderedFeatures([[x-r, y-r], [x+r,y+r]]);
// ignore the basemap // ignore the basemap
features = features.filter((feature) => feature.source === "source"); features = features.filter((feature) => feature.source === "source");
map.getCanvas().style.cursor = features.length ? "pointer" : ""; for (const feature of features) {
map.setFeatureState(feature, {hover: true});
hoveredFeatures.add(feature);
}
let content = renderToString(<FeaturesProperties features={features} />); let content = renderToString(<FeaturesProperties features={features} />);
if (!features.length) { if (!features.length) {