mirror of
https://github.com/zadam/trilium.git
synced 2026-03-09 21:50:24 +01:00
chore(collections/map): bring back colors
This commit is contained in:
@@ -4,24 +4,39 @@ import FNote from "../../../entities/fnote";
|
||||
import { useChildNotes } from "../../react/hooks";
|
||||
import { LOCATION_ATTRIBUTE } from ".";
|
||||
|
||||
const DEFAULT_MARKER_COLOR = "#2A81CB";
|
||||
|
||||
// SVG marker pin shape (replaces the Leaflet marker PNG).
|
||||
export const MARKER_SVG = `<svg width="25" height="41" viewBox="0 0 25 41" xmlns="http://www.w3.org/2000/svg">` +
|
||||
`<path d="M12.5 0C5.6 0 0 5.6 0 12.5C0 21.9 12.5 41 12.5 41S25 21.9 25 12.5C25 5.6 19.4 0 12.5 0Z" fill="#2A81CB" />` +
|
||||
`<circle cx="12.5" cy="12.5" r="8" fill="white" />` +
|
||||
`</svg>`;
|
||||
export const MARKER_SVG = buildMarkerIcon();
|
||||
|
||||
function buildMarkerIcon(color = DEFAULT_MARKER_COLOR) {
|
||||
return `\
|
||||
<svg width="25" height="41" viewBox="0 0 25 41" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5 0C5.6 0 0 5.6 0 12.5C0 21.9 12.5 41 12.5 41S25 21.9 25 12.5C25 5.6 19.4 0 12.5 0Z" fill="${color}" />
|
||||
<circle cx="12.5" cy="12.5" r="8" fill="white" />
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
|
||||
export function useMarkerData(note: FNote | null | undefined, apiRef: MutableRef<maplibregl.Map>) {
|
||||
const childNotes = useChildNotes(note?.noteId);
|
||||
|
||||
useEffect(() => {
|
||||
async function refresh() {
|
||||
const map = apiRef.current as maplibregl.Map | undefined;
|
||||
if (!map) return;
|
||||
|
||||
svgToImage(MARKER_SVG, (img) => {
|
||||
map.addImage("custom-marker", img, {
|
||||
pixelRatio: window.devicePixelRatio
|
||||
});
|
||||
});
|
||||
const iconSvgCache = new Map<string, string>();
|
||||
|
||||
function ensureIcon(color: string) {
|
||||
const key = `marker-${color}`;
|
||||
|
||||
if (!iconSvgCache.has(key)) {
|
||||
const svg = buildMarkerIcon(color);
|
||||
iconSvgCache.set(key, svg);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
const features: maplibregl.GeoJSONFeature[] = [];
|
||||
for (const childNote of childNotes) {
|
||||
@@ -30,6 +45,7 @@ export function useMarkerData(note: FNote | null | undefined, apiRef: MutableRef
|
||||
if (!latLng) continue;
|
||||
latLng.reverse();
|
||||
|
||||
const color = childNote.getLabelValue("color") ?? DEFAULT_MARKER_COLOR;
|
||||
features.push({
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
@@ -39,10 +55,17 @@ export function useMarkerData(note: FNote | null | undefined, apiRef: MutableRef
|
||||
properties: {
|
||||
id: childNote.noteId,
|
||||
name: childNote.title,
|
||||
icon: ensureIcon(color)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Build all the icons.
|
||||
await Promise.all(iconSvgCache.entries().map(async ([ key, svg ]) => {
|
||||
const image = await svgToImage(svg);
|
||||
map.addImage(key, image);
|
||||
}));
|
||||
|
||||
map.addSource("points", {
|
||||
type: "geojson",
|
||||
data: {
|
||||
@@ -55,30 +78,31 @@ export function useMarkerData(note: FNote | null | undefined, apiRef: MutableRef
|
||||
type: "symbol",
|
||||
source: "points",
|
||||
layout: {
|
||||
"icon-image": "custom-marker",
|
||||
"icon-image": [ "get", "icon" ],
|
||||
"icon-size": 1,
|
||||
"icon-anchor": "bottom",
|
||||
"icon-allow-overlap": true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
map.removeLayer("points-layer");
|
||||
map.removeSource("points");
|
||||
};
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
}, [ apiRef, childNotes ]);
|
||||
}
|
||||
|
||||
function svgToImage(svgString, callback) {
|
||||
const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
|
||||
const url = URL.createObjectURL(svgBlob);
|
||||
function svgToImage(svgString){
|
||||
return new Promise<HTMLImageElement>(resolve => {
|
||||
const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
|
||||
const url = URL.createObjectURL(svgBlob);
|
||||
|
||||
const img = new Image();
|
||||
const img = new Image();
|
||||
|
||||
img.onload = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
callback(img);
|
||||
};
|
||||
img.onload = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
resolve(img);
|
||||
};
|
||||
|
||||
img.src = url;
|
||||
img.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user