server_photo_s85js/public/js/map/clusterIcons.js
2026-08-11 08:45:04 +02:00

141 lines
2.9 KiB
JavaScript

// public/js/map/clusterIcons.js
// ===============================
// CLUSTER ICONS
// ===============================
(function () {
"use strict";
function getFirstMarkers(cluster, limit = 4) {
const result = [];
const stack = [cluster];
while (stack.length && result.length < limit) {
const node = stack.pop();
if (node._markers?.length) {
for (const marker of node._markers) {
result.push(marker);
if (result.length >= limit) {
break;
}
}
}
if (result.length >= limit) {
break;
}
if (node._childClusters?.length) {
for (let i = node._childClusters.length - 1; i >= 0; i--) {
stack.push(node._childClusters[i]);
}
}
}
return result;
}
window.createPhotoClusterHtml = function ({ count, thumbs = [] }) {
const size = Math.min(92, Math.round(28 + Math.sqrt(count) * 6));
const cls =
count > 200
? "cluster-xl"
: count > 50
? "cluster-lg"
: count > 10
? "cluster-md"
: "cluster-sm";
const collage = thumbs.length
? `
<div class="cluster-collage">
${thumbs
.map(
(src, index) => `
<div class="c${index}">
<img src="${src}" />
</div>
`,
)
.join("")}
</div>
`
: "";
return {
size,
html: `
<div class="gp-cluster ${cls}"
style="width:${size}px;height:${size}px;">
${collage}
<div class="gp-count">
<span>${count}</span>
</div>
</div>
`,
};
};
function getPhotoClusterData(cluster) {
const count = cluster.getChildCount();
const size = Math.min(92, Math.round(28 + Math.sqrt(count) * 6));
const cls =
count > 200
? "cluster-xl"
: count > 50
? "cluster-lg"
: count > 10
? "cluster-md"
: "cluster-sm";
const thumbs = getFirstMarkers(cluster)
.map((marker) => marker.__thumb)
.filter(Boolean);
return {
count,
size,
cls,
thumbs,
};
}
window.createPhotoClusterIcon = function (cluster) {
const { count, size, cls, thumbs } = getPhotoClusterData(cluster);
const collage = thumbs.length
? `
<div class="cluster-collage">
${thumbs
.map(
(src, index) => `
<div class="c${index}">
<img src="${src}" />
</div>
`,
)
.join("")}
</div>
`
: "";
return L.divIcon({
html: `
<div class="gp-cluster ${cls}"
style="width:${size}px;height:${size}px;">
${collage}
<div class="gp-count">
<span>${count}</span>
</div>
</div>
`,
className: "marker-cluster-wrapper",
iconSize: L.point(size, size),
});
};
})();