141 lines
2.9 KiB
JavaScript
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),
|
|
});
|
|
};
|
|
})();
|