This commit is contained in:
“chrisshank” 2024-11-16 15:45:55 -08:00
parent fa7c623002
commit ea6f7934ec
4 changed files with 61 additions and 57 deletions

View File

@ -19,7 +19,7 @@
margin: 0;
}
leaflet-map,
folk-map,
geo-wiki {
display: block;
height: 100%;
@ -38,34 +38,27 @@
</head>
<body>
<fc-geometry x="25" y="100" width="400" height="200">
<leaflet-map coordinates="52.09, 5.12" zoom="13"></leaflet-map>
<folk-map coordinates="52.09, 5.12" zoom="13"></folk-map>
</fc-geometry>
<fc-geometry x="50" y="550" width="400" height="250">
<leaflet-map
coordinates="51.50404120260676, -0.14007568359375003"
zoom="13"
></leaflet-map>
<folk-map coordinates="51.50404120260676, -0.14007568359375003" zoom="13"></folk-map>
</fc-geometry>
<fc-geometry x="500" y="400" width="500" height="300">
<geo-wiki
coordinates="51.50404120260676, -0.14007568359375003"
></geo-wiki>
<geo-wiki coordinates="51.50404120260676, -0.14007568359375003"></geo-wiki>
</fc-geometry>
<script type="module">
import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { LeafletMap } from '../src/maps';
import { FolkMap } from '../src/maps';
FolkGeometry.register();
LeafletMap.register();
FolkMap.register();
function collisionDetection(rect1, rect2) {
return (
rect1.left < rect2.right &&
rect1.right > rect2.left &&
rect1.top < rect2.bottom &&
rect1.bottom > rect2.top
rect1.left < rect2.right && rect1.right > rect2.left && rect1.top < rect2.bottom && rect1.bottom > rect2.top
);
}
@ -81,12 +74,7 @@
);
}
const proximityMap = new Map(
Array.from(document.querySelectorAll('fc-geometry')).map((el) => [
el,
new Set(),
])
);
const proximityMap = new Map(Array.from(document.querySelectorAll('fc-geometry')).map((el) => [el, new Set()]));
function handleProximity(e) {
proximityMap.forEach((set, el) => {
@ -124,7 +112,7 @@
proximityMap.get(e.target.parentElement)?.forEach((el) => {
const content = el.firstElementChild;
if (content instanceof GeoWiki) {
const { lat, lng } = e.detail;
const { lat, lng } = e.target.coordinates;
content.coordinates = [lat, lng];
}
});
@ -152,9 +140,7 @@
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'coordinates') {
this.#coordinates = newValue
.split(',')
.map((str) => Number(str)) || [0, 0];
this.#coordinates = newValue.split(',').map((str) => Number(str)) || [0, 0];
this.searchWiki(this.#coordinates);
}
}
@ -170,9 +156,7 @@
origin: '*',
});
// https://www.mediawiki.org/wiki/API:Geosearch
this.#results = await fetch(
`https://en.wikipedia.org/w/api.php?${params}`
)
this.#results = await fetch(`https://en.wikipedia.org/w/api.php?${params}`)
.then((response) => response.json())
.then((data) => data?.query?.geosearch ?? []);

View File

@ -5,6 +5,7 @@
"preview": "vite build demo && vite preview demo"
},
"imports": {
"@types/leaflet": "npm:@types/leaflet@^1.9.14",
"perfect-arrows": "npm:perfect-arrows@^0.3.7",
"perfect-freehand": "npm:perfect-freehand@^1.2.2",
"leaflet": "npm:leaflet@^1.9.4",

View File

@ -1,6 +1,7 @@
{
"version": "4",
"specifiers": {
"npm:@types/leaflet@^1.9.14": "1.9.14",
"npm:leaflet@^1.9.4": "1.9.4",
"npm:perfect-arrows@~0.3.7": "0.3.7",
"npm:perfect-freehand@^1.2.2": "1.2.2",
@ -134,6 +135,15 @@
"@types/estree@1.0.6": {
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
},
"@types/geojson@7946.0.14": {
"integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg=="
},
"@types/leaflet@1.9.14": {
"integrity": "sha512-sx2q6MDJaajwhKeVgPSvqXd8rhNJSTA3tMidQGduZn9S6WBYxDkCpSpV5xXEmSg7Cgdk/5vJGhVF1kMYLzauBg==",
"dependencies": [
"@types/geojson"
]
},
"esbuild@0.21.5": {
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
"dependencies": [
@ -228,6 +238,7 @@
},
"workspace": {
"dependencies": [
"npm:@types/leaflet@^1.9.14",
"npm:leaflet@^1.9.4",
"npm:perfect-arrows@~0.3.7",
"npm:perfect-freehand@^1.2.2",

View File

@ -1,15 +1,8 @@
import {
LatLng,
LatLngExpression,
LeafletEvent,
map,
Map,
tileLayer,
} from "leaflet";
import { LatLng, LatLngExpression, LeafletEvent, map, Map, tileLayer } from 'leaflet';
// @ts-ignore
// Vite specific import :(
import css from "leaflet/dist/leaflet.css?inline";
import css from 'leaflet/dist/leaflet.css?inline';
const styles = new CSSStyleSheet();
styles.replaceSync(`${css}
:host {
@ -22,54 +15,69 @@ styles.replaceSync(`${css}
}
`);
export class RecenterEvent extends CustomEvent<LatLng> {
constructor(detail: LatLng) {
super("recenter", { detail, bubbles: true });
export class RecenterEvent extends Event {
constructor() {
super('recenter', { bubbles: true });
}
}
export class LeafletMap extends HTMLElement {
static tagName = "leaflet-map";
export class FolkMap extends HTMLElement {
static tagName = 'folk-map';
static register() {
customElements.define(this.tagName, this);
}
#container = document.createElement("div");
#container = document.createElement('div');
#map!: Map;
constructor() {
super();
this.handleEvent = this.handleEvent.bind(this);
const shadow = this.attachShadow({ mode: "open" });
const shadow = this.attachShadow({ mode: 'open' });
shadow.adoptedStyleSheets.push(styles);
shadow.appendChild(this.#container);
}
get coordinates() {
return this.#map.getCenter();
}
set coordinates(coordinates) {
this.#map.setView(coordinates);
}
get zoom() {
return this.#map.getZoom();
}
set zoom(zoom) {
this.#map.setZoom(zoom);
}
connectedCallback() {
this.#map = map(this.#container);
this.#map.addLayer(
tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution:
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
})
);
const coordinates = (this.getAttribute("coordinates")
?.split(",")
.map((str) => Number(str)) || [0, 0]) as LatLngExpression;
const zoom = Number(this.getAttribute("zoom") || 13);
this.#map.setView(coordinates, zoom);
this.#map.on("zoom", this.handleEvent);
this.#map.on("moveend", this.handleEvent);
this.#map.on('zoom', this.handleEvent);
this.#map.on('moveend', this.handleEvent);
this.#map.setView(
(this.getAttribute('coordinates') || '0, 0').split(',').map(Number) as LatLngExpression,
Number(this.getAttribute('zoom') || 13)
);
}
handleEvent(event: LeafletEvent) {
switch (event.type) {
case "zoom":
case "moveend": {
this.dispatchEvent(new RecenterEvent(this.#map.getCenter()));
case 'zoom':
case 'moveend': {
this.dispatchEvent(new RecenterEvent());
break;
}
}