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

View File

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

View File

@ -1,6 +1,7 @@
{ {
"version": "4", "version": "4",
"specifiers": { "specifiers": {
"npm:@types/leaflet@^1.9.14": "1.9.14",
"npm:leaflet@^1.9.4": "1.9.4", "npm:leaflet@^1.9.4": "1.9.4",
"npm:perfect-arrows@~0.3.7": "0.3.7", "npm:perfect-arrows@~0.3.7": "0.3.7",
"npm:perfect-freehand@^1.2.2": "1.2.2", "npm:perfect-freehand@^1.2.2": "1.2.2",
@ -134,6 +135,15 @@
"@types/estree@1.0.6": { "@types/estree@1.0.6": {
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" "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": { "esbuild@0.21.5": {
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
"dependencies": [ "dependencies": [
@ -228,6 +238,7 @@
}, },
"workspace": { "workspace": {
"dependencies": [ "dependencies": [
"npm:@types/leaflet@^1.9.14",
"npm:leaflet@^1.9.4", "npm:leaflet@^1.9.4",
"npm:perfect-arrows@~0.3.7", "npm:perfect-arrows@~0.3.7",
"npm:perfect-freehand@^1.2.2", "npm:perfect-freehand@^1.2.2",

View File

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