feat: add new control to leaflet web component

This commit is contained in:
log101 2024-07-21 11:45:55 +03:00
parent d0df5fbbc6
commit fb31a822a0
4 changed files with 80 additions and 18 deletions

View File

@ -0,0 +1,19 @@
import L from "leaflet";
const TargetLocationControl = L.Control.extend({
onAdd: function (map: L.Map, targetLocation: L.LatLngTuple) {
const locationButton = document.createElement("button");
locationButton.textContent = "Hedefe Git";
locationButton.classList.add("custom-map-control-button");
locationButton.addEventListener("click", () => {
map.setView(targetLocation, 18);
});
return locationButton;
},
});
export { TargetLocationControl };

View File

@ -0,0 +1,13 @@
import { icon } from "leaflet";
var targetLocationIcon = icon({
iconUrl: "goal.svg",
iconSize: [32, 32],
});
var currentLocationIcon = icon({
iconUrl: "blue-dot.png",
iconSize: [32, 32],
});
export { targetLocationIcon, currentLocationIcon };

View File

@ -1,18 +1,34 @@
// Lit
import { html, LitElement } from "lit";
import { html, LitElement, unsafeCSS, type CSSResultGroup } from "lit";
import { customElement, property, query, state } from "lit/decorators.js";
// Leaflet
import L from "leaflet";
import L, { Map } from "leaflet";
import type { LatLngTuple } from "leaflet";
import { targetLocationIcon } from "./LeafletMap/icons";
import { TargetLocationControl } from "./LeafletMap/controls";
// Styles
import leafletStyles from "leaflet/dist/leaflet.css?inline";
import globalStyles from "@/styles/globals.css?inline";
import mapStyles from "@/styles/locked-page.css?inline";
@customElement("leaflet-map")
export class LeafletMap extends LitElement {
@property({ type: Object }) targetLocation?: LatLngTuple;
// Styles
static styles?: CSSResultGroup | undefined = [
unsafeCSS(leafletStyles),
unsafeCSS(globalStyles),
unsafeCSS(mapStyles),
];
@query("#leaflet-map-container")
// Div element to initialize Leaflet in
@query("#mapid")
_mapElement!: HTMLDivElement;
// Properties and states
@property({ type: Object }) targetLocation?: LatLngTuple;
@state()
protected _map?: L.Map;
@state()
@ -22,8 +38,32 @@ export class LeafletMap extends LitElement {
@state()
protected _watchingLocation = false;
connectedCallback(): void {
super.connectedCallback();
firstUpdated(): void {
if (!this._mapElement || !this.targetLocation) return;
var map = new Map(this._mapElement).setView(this.targetLocation, 13);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
// Add target location icon marker
L.marker(this.targetLocation, { icon: targetLocationIcon }).addTo(map);
L.circle(this.targetLocation, {
color: "blue",
fillColor: "#30f",
fillOpacity: 0.2,
radius: 50,
}).addTo(map);
// Add target location control
const targetLocationControl = new TargetLocationControl({
position: "bottomleft",
});
targetLocationControl.addTo(map);
// Check geolocation permission, if user has given permission before
// start watching user location
@ -44,9 +84,6 @@ export class LeafletMap extends LitElement {
}
render() {
return html`<div
id="leaflet-map-container"
class="w-full h-[450px] rounded"
></div>`;
return html`<div id="mapid" class="w-full h-[450px] rounded"></div>`;
}
}

View File

@ -71,13 +71,6 @@ const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc());
<leaflet-map targetLocation={data?.loc}></leaflet-map>
<div
id="map"
class="w-full h-[450px] rounded"
data-target-location={data?.loc}
>
</div>
<ShareButton client:only />
<div class="flex justify-center">
<p class="text-muted-foreground">
@ -85,7 +78,7 @@ const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc());
</p>
</div>
</main>
<script src="../scripts/initMap.ts"></script>
<!-- <script src="../scripts/initMap.ts"></script> -->
<script src="../components/locked-content.ts"></script>
<script src="../components/leaflet-map.ts"></script>
</Layout>