working proximity
This commit is contained in:
parent
17450f64b9
commit
aa87c39a28
|
|
@ -59,7 +59,7 @@
|
||||||
<body>
|
<body>
|
||||||
<folk-proximity>
|
<folk-proximity>
|
||||||
<fc-geometry id="g1" x="25" y="100" width="400" height="200">
|
<fc-geometry id="g1" x="25" y="100" width="400" height="200">
|
||||||
<folk-map coordinates="52.09, 5.12" zoom="13"></folk-map>
|
<folk-map coordinates="40.76845173617708, -73.97983074188234" zoom="15"></folk-map>
|
||||||
</fc-geometry>
|
</fc-geometry>
|
||||||
|
|
||||||
<fc-geometry id="g2" x="50" y="600" width="400" height="250">
|
<fc-geometry id="g2" x="50" y="600" width="400" height="250">
|
||||||
|
|
@ -67,11 +67,11 @@
|
||||||
</fc-geometry>
|
</fc-geometry>
|
||||||
|
|
||||||
<fc-geometry id="g3" x="500" y="500" width="500" height="300">
|
<fc-geometry id="g3" x="500" y="500" width="500" height="300">
|
||||||
<geo-wiki coordinates="51.50404120260676, -0.14007568359375003"></geo-wiki>
|
<geo-wiki></geo-wiki>
|
||||||
</fc-geometry>
|
</fc-geometry>
|
||||||
|
|
||||||
<fc-geometry id="g4" x="450" y="100">
|
<fc-geometry id="g4" x="450" y="100">
|
||||||
<folk-weather coordinates="51.50404120260676, -0.14007568359375003"></folk-weather>
|
<folk-weather></folk-weather>
|
||||||
</fc-geometry>
|
</fc-geometry>
|
||||||
</folk-proximity>
|
</folk-proximity>
|
||||||
|
|
||||||
|
|
@ -81,12 +81,6 @@
|
||||||
import { FolkWeather } from '../src/folk-weather.ts';
|
import { FolkWeather } from '../src/folk-weather.ts';
|
||||||
import { FolkCluster, FolkProximity } from '../src/folk-proximity.ts';
|
import { FolkCluster, FolkProximity } from '../src/folk-proximity.ts';
|
||||||
|
|
||||||
FolkGeometry.define();
|
|
||||||
FolkMap.define();
|
|
||||||
FolkCluster.define();
|
|
||||||
FolkProximity.define();
|
|
||||||
FolkWeather.define();
|
|
||||||
|
|
||||||
class GeoWiki extends HTMLElement {
|
class GeoWiki extends HTMLElement {
|
||||||
static tagName = 'geo-wiki';
|
static tagName = 'geo-wiki';
|
||||||
|
|
||||||
|
|
@ -150,6 +144,50 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FolkCluster.registerElement({
|
||||||
|
constructor: FolkMap,
|
||||||
|
events: {
|
||||||
|
recenter: (e) => ({
|
||||||
|
lat: e.target.coordinates.lat,
|
||||||
|
lng: e.target.coordinates.lng,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
onAdd: (element) => ({
|
||||||
|
lat: element.coordinates.lat,
|
||||||
|
lng: element.coordinates.lng,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
FolkCluster.registerElement({
|
||||||
|
constructor: FolkWeather,
|
||||||
|
onAdd: console.log,
|
||||||
|
onUpdate(element, data, changes) {
|
||||||
|
const lat = data.get('lat');
|
||||||
|
const lng = data.get('lng');
|
||||||
|
|
||||||
|
if (lat && lng) {
|
||||||
|
element.coordinates = [lat, lng];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
FolkCluster.registerElement({
|
||||||
|
constructor: GeoWiki,
|
||||||
|
onUpdate(element, data, changes) {
|
||||||
|
const lat = data.get('lat');
|
||||||
|
const lng = data.get('lng');
|
||||||
|
|
||||||
|
if (lat && lng) {
|
||||||
|
element.coordinates = [lat, lng];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
FolkGeometry.define();
|
||||||
|
FolkMap.define();
|
||||||
|
FolkCluster.define();
|
||||||
|
FolkProximity.define();
|
||||||
|
FolkWeather.define();
|
||||||
GeoWiki.define();
|
GeoWiki.define();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,18 @@ import { collisionDetection } from './collision';
|
||||||
import { FolkHull } from './folk-hull';
|
import { FolkHull } from './folk-hull';
|
||||||
import { FolkGeometry } from './canvas/fc-geometry.ts';
|
import { FolkGeometry } from './canvas/fc-geometry.ts';
|
||||||
|
|
||||||
|
interface ElementConstructor<E extends Element = Element> {
|
||||||
|
new (): E;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ElementConfig<E extends Element = Element> {
|
||||||
|
constructor: ElementConstructor<E>;
|
||||||
|
events?: Record<string, (event: Event) => Record<string, any>>;
|
||||||
|
onAdd?(element: E): void | Record<string, any>;
|
||||||
|
onUpdate?(element: E, data: ReadonlyMap<string, any>, updatedValues: Set<string>): void;
|
||||||
|
onRemove?(element: E): void;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO don't hard code this
|
// TODO don't hard code this
|
||||||
const PROXIMITY = 50;
|
const PROXIMITY = 50;
|
||||||
|
|
||||||
|
|
@ -15,6 +27,12 @@ declare global {
|
||||||
export class FolkCluster extends FolkHull {
|
export class FolkCluster extends FolkHull {
|
||||||
static tagName = 'folk-cluster';
|
static tagName = 'folk-cluster';
|
||||||
|
|
||||||
|
static #config = new Map<ElementConstructor, ElementConfig>();
|
||||||
|
|
||||||
|
static registerElement<E extends Element>(config: ElementConfig<E>) {
|
||||||
|
this.#config.set(config.constructor, config);
|
||||||
|
}
|
||||||
|
|
||||||
#data = new Map();
|
#data = new Map();
|
||||||
|
|
||||||
isElementInCluster(element: FolkGeometry) {
|
isElementInCluster(element: FolkGeometry) {
|
||||||
|
|
@ -28,18 +46,85 @@ export class FolkCluster extends FolkHull {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
addElements(...elements) {
|
addElements(...elements: FolkGeometry[]) {
|
||||||
this.sources = this.sourceElements
|
this.sources = this.sourceElements
|
||||||
.concat(elements)
|
.concat(elements)
|
||||||
.map((el) => `#${el.id}`)
|
.map((el) => `#${el.id}`)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
|
let data = {};
|
||||||
|
|
||||||
|
for (const geometry of elements) {
|
||||||
|
const element = geometry.firstElementChild;
|
||||||
|
|
||||||
|
if (element === null) continue;
|
||||||
|
|
||||||
|
const config = this.#getConfig(element);
|
||||||
|
|
||||||
|
if (config) {
|
||||||
|
for (const event of Object.keys(config.events || {})) {
|
||||||
|
element.addEventListener(event, this.#handleEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newData = config.onAdd?.(element);
|
||||||
|
data = Object.assign(data, newData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#handleUpdate(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeElement(element) {
|
#handleEvent = (event: Event) => {
|
||||||
|
const config = this.#getConfig(event.currentTarget as Element);
|
||||||
|
|
||||||
|
if (config) {
|
||||||
|
const data = config.events?.[event.type]?.(event);
|
||||||
|
if (data === undefined) return;
|
||||||
|
this.#handleUpdate(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#handleUpdate(data: Record<string, any>) {
|
||||||
|
const keys = new Set(Object.keys(data));
|
||||||
|
for (const key of keys) {
|
||||||
|
this.#data.set(key, data[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const geometry of this.sourceElements) {
|
||||||
|
const element = geometry.firstElementChild;
|
||||||
|
|
||||||
|
if (element === null) continue;
|
||||||
|
|
||||||
|
const config = this.#getConfig(element);
|
||||||
|
|
||||||
|
config?.onUpdate?.(element, this.#data, keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeElement(geometry: FolkGeometry) {
|
||||||
this.sources = this.sourceElements
|
this.sources = this.sourceElements
|
||||||
.filter((el) => el !== element)
|
.filter((el) => el !== geometry)
|
||||||
.map((el) => `#${el.id}`)
|
.map((el) => `#${el.id}`)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
|
const element = geometry.firstElementChild;
|
||||||
|
|
||||||
|
if (element === null) return;
|
||||||
|
|
||||||
|
const config = this.#getConfig(element);
|
||||||
|
|
||||||
|
if (config) {
|
||||||
|
for (const event of Object.keys(config.events || {})) {
|
||||||
|
element.removeEventListener(event, this.#handleEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.onRemove?.(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#getConfig(element: Element) {
|
||||||
|
const config = (this.constructor as typeof FolkCluster).#config;
|
||||||
|
return config.get(element.constructor as ElementConstructor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,15 +143,6 @@ export class FolkProximity extends HTMLElement {
|
||||||
|
|
||||||
this.addEventListener('move', this.#handleProximity);
|
this.addEventListener('move', this.#handleProximity);
|
||||||
this.addEventListener('resize', this.#handleProximity);
|
this.addEventListener('resize', this.#handleProximity);
|
||||||
// document.addEventListener('recenter', (e) => {
|
|
||||||
// proximityMap.get(e.target.parentElement)?.forEach((el) => {
|
|
||||||
// const content = el.firstElementChild;
|
|
||||||
// if (content instanceof GeoWiki) {
|
|
||||||
// const { lat, lng } = e.target.coordinates;
|
|
||||||
// content.coordinates = [lat, lng];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#handleProximity = (e) => {
|
#handleProximity = (e) => {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultRect = DOMRectReadOnly.fromRect();
|
||||||
|
|
||||||
export class FolkSet extends HTMLElement {
|
export class FolkSet extends HTMLElement {
|
||||||
static tagName = 'folk-set';
|
static tagName = 'folk-set';
|
||||||
|
|
||||||
|
|
@ -60,6 +62,7 @@ export class FolkSet extends HTMLElement {
|
||||||
this.unobserveSources(elementsToUnobserve);
|
this.unobserveSources(elementsToUnobserve);
|
||||||
|
|
||||||
for (const el of elementsToObserve) {
|
for (const el of elementsToObserve) {
|
||||||
|
this.#sourcesMap.set(el, defaultRect);
|
||||||
clientRectObserver.observe(el, this.#sourcesCallback);
|
clientRectObserver.observe(el, this.#sourcesCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue