Compare commits
2 commits
925e98aea7
...
75d3b557fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75d3b557fe | ||
|
|
b19635f324 |
7 changed files with 131 additions and 28 deletions
|
|
@ -55,3 +55,24 @@ tabs:
|
|||
type: map-editor
|
||||
mode: single
|
||||
help: Déplacez le marqueur
|
||||
markerIcon:
|
||||
label: Icône personnalisée
|
||||
type: files
|
||||
multiple: false
|
||||
accept:
|
||||
- image/jpeg
|
||||
- image/png
|
||||
- image/svg+xml
|
||||
width: 1/2
|
||||
help: Image à utiliser comme marqueur (JPG, PNG ou SVG). Laissez vide pour utiliser le marqueur par défaut.
|
||||
|
||||
markerIconSize:
|
||||
label: Taille de l'icône
|
||||
type: range
|
||||
min: 20
|
||||
max: 500
|
||||
step: 5
|
||||
default: 40
|
||||
after: px
|
||||
width: 1/2
|
||||
help: Taille de l'icône en pixels
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -28,6 +28,23 @@ Kirby::plugin('geoproject/map-editor', [
|
|||
},
|
||||
'longitude' => function ($longitude = null) {
|
||||
return $longitude;
|
||||
},
|
||||
'markerIconUrl' => function ($markerIconUrl = null) {
|
||||
// Auto-detect marker icon from page files
|
||||
if ($markerIconUrl === null && $this->model()) {
|
||||
$iconFile = $this->model()->markerIcon()->toFile();
|
||||
if ($iconFile) {
|
||||
return $iconFile->url();
|
||||
}
|
||||
}
|
||||
return $markerIconUrl;
|
||||
},
|
||||
'markerIconSize' => function ($markerIconSize = 40) {
|
||||
// Auto-detect marker icon size from page
|
||||
if ($this->model() && $this->model()->markerIconSize()->isNotEmpty()) {
|
||||
return (int) $this->model()->markerIconSize()->value();
|
||||
}
|
||||
return $markerIconSize;
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -79,6 +79,14 @@ export default {
|
|||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
markerIconUrl: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
markerIconSize: {
|
||||
type: Number,
|
||||
default: 40,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props, { emit }) {
|
||||
|
|
@ -138,6 +146,8 @@ export default {
|
|||
id: 'single-marker',
|
||||
position: { lat, lon },
|
||||
title: 'Current position',
|
||||
iconUrl: props.markerIconUrl,
|
||||
iconSize: props.markerIconSize,
|
||||
}];
|
||||
}
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ export default {
|
|||
font-size: 0.875rem;
|
||||
background: var(--color-white);
|
||||
transition: border-color 0.2s;
|
||||
color: #000;
|
||||
color: #fff;
|
||||
background: var(--input-color-back);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,6 +181,25 @@ export default {
|
|||
const el = document.createElement("div");
|
||||
el.className = "custom-marker";
|
||||
|
||||
// Check if custom icon is provided
|
||||
if (markerData.iconUrl) {
|
||||
// Use custom image
|
||||
el.classList.add("custom-icon");
|
||||
const img = document.createElement("img");
|
||||
img.src = markerData.iconUrl;
|
||||
img.className = "marker-icon-image";
|
||||
|
||||
// Set size from marker data or default to 40px
|
||||
const size = markerData.iconSize || 40;
|
||||
img.style.width = `${size}px`;
|
||||
img.style.height = `${size}px`;
|
||||
|
||||
if (props.selectedMarkerId === markerData.id) {
|
||||
img.classList.add("selected");
|
||||
}
|
||||
el.appendChild(img);
|
||||
} else {
|
||||
// Use default pin marker
|
||||
// Create inner wrapper for visual transforms (isolates from MapLibre transforms)
|
||||
const inner = document.createElement("div");
|
||||
inner.className = "marker-inner";
|
||||
|
|
@ -194,6 +213,7 @@ export default {
|
|||
numberEl.textContent = index + 1;
|
||||
inner.appendChild(numberEl);
|
||||
el.appendChild(inner);
|
||||
}
|
||||
|
||||
try {
|
||||
const coords = [markerData.position.lon, markerData.position.lat];
|
||||
|
|
@ -252,6 +272,7 @@ export default {
|
|||
function updateMarkerSelection(selectedId) {
|
||||
markerElements.value.forEach(({ element }, markerId) => {
|
||||
if (element) {
|
||||
// Handle default pin marker
|
||||
const inner = element.querySelector('.marker-inner');
|
||||
if (inner) {
|
||||
if (markerId === selectedId) {
|
||||
|
|
@ -260,6 +281,16 @@ export default {
|
|||
inner.classList.remove("selected");
|
||||
}
|
||||
}
|
||||
|
||||
// Handle custom icon marker
|
||||
const img = element.querySelector('.marker-icon-image');
|
||||
if (img) {
|
||||
if (markerId === selectedId) {
|
||||
img.classList.add("selected");
|
||||
} else {
|
||||
img.classList.remove("selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -399,6 +430,30 @@ export default {
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Custom icon marker */
|
||||
.custom-marker.custom-icon {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.custom-marker.custom-icon:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.marker-icon-image {
|
||||
object-fit: contain;
|
||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.marker-icon-image:hover {
|
||||
transform: scale(1.1);
|
||||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.4));
|
||||
}
|
||||
|
||||
.marker-icon-image.selected {
|
||||
filter: drop-shadow(0 4px 12px rgba(52, 152, 219, 0.8));
|
||||
}
|
||||
|
||||
/* MapLibre controls styling */
|
||||
.maplibregl-ctrl-group {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue