fix base-set

This commit is contained in:
“chrisshank” 2024-12-10 11:48:09 -08:00
parent fabc27200c
commit 18bcb91e8d
4 changed files with 67 additions and 63 deletions

View File

@ -39,10 +39,10 @@
<body>
<h1>This is a Convex Hull</h1>
<folk-hull sources="h1, body > folk-shape"></folk-hull>
<folk-shape x="50" y="100" width="50" height="50"></folk-shape>
<folk-shape x="200" y="200" width="50" height="50"></folk-shape>
<folk-shape x="100" y="300" width="50" height="50"></folk-shape>
<folk-hull sources="h1, body > folk-shape"></folk-hull>
<folk-hull sources="h1">
<folk-shape x="350" y="100" width="50" height="50"></folk-shape>

View File

@ -22,19 +22,47 @@ export class FolkBaseConnection extends FolkElement {
override disconnectedCallback() {
super.disconnectedCallback();
this.unobserveSource();
this.unobserveTarget();
this.#unobserveSource();
this.#unobserveTarget();
}
override willUpdate(changedProperties: PropertyValues<this>) {
super.willUpdate(changedProperties);
if (changedProperties.has('source')) {
this.observeSource();
this.#unobserveSource();
const vertex = parseVertex(this.source);
if (vertex) {
this.sourceRect = DOMRectReadOnly.fromRect(vertex);
} else {
this.sourceElement = document.querySelector(this.source);
if (this.sourceElement === null) {
this.sourceRect = null;
} else {
folkObserver.observe(this.sourceElement, this.#sourceCallback);
}
}
}
if (changedProperties.has('target')) {
this.observeTarget();
this.#unobserveTarget();
const vertex = parseVertex(this.target);
if (vertex) {
this.targetRect = DOMRectReadOnly.fromRect(vertex);
} else {
this.targetElement = document.querySelector(this.target);
if (this.targetElement === null) {
this.targetRect = null;
} else {
folkObserver.observe(this.targetElement, this.#targetCallback);
}
}
}
}
@ -42,25 +70,7 @@ export class FolkBaseConnection extends FolkElement {
this.sourceRect = entry.contentRect;
};
observeSource() {
this.unobserveSource();
const vertex = parseVertex(this.source);
if (vertex) {
this.sourceRect = DOMRectReadOnly.fromRect(vertex);
} else {
this.sourceElement = document.querySelector(this.source);
if (this.sourceElement === null) {
this.sourceRect = null;
} else {
folkObserver.observe(this.sourceElement, this.#sourceCallback);
}
}
}
unobserveSource() {
#unobserveSource() {
if (this.sourceElement === null) return;
folkObserver.unobserve(this.sourceElement, this.#sourceCallback);
@ -70,25 +80,7 @@ export class FolkBaseConnection extends FolkElement {
this.targetRect = entry.contentRect;
};
observeTarget() {
this.unobserveTarget();
const vertex = parseVertex(this.target);
if (vertex) {
this.targetRect = DOMRectReadOnly.fromRect(vertex);
} else {
this.targetElement = document.querySelector(this.target);
if (this.targetElement === null) {
this.targetRect = null;
} else {
folkObserver.observe(this.targetElement, this.#targetCallback);
}
}
}
unobserveTarget() {
#unobserveTarget() {
if (this.targetElement === null) return;
folkObserver.unobserve(this.targetElement, this.#targetCallback);
}

View File

@ -6,6 +6,7 @@ import { PropertyValues } from '@lit/reactive-element';
const folkObserver = new FolkObserver();
// TODO: use mutation observer to track the addition an removal of elements
export class FolkBaseSet extends FolkElement {
@property({ type: String, reflect: true }) sources = '';
@ -20,25 +21,33 @@ export class FolkBaseSet extends FolkElement {
@state() sourceElements = new Set<Element>();
#sourcesCallback = (entry: ClientRectObserverEntry) => {
this.#sourcesMap.set(entry.target, entry.contentRect);
this.requestUpdate();
};
#slot = document.createElement('slot');
disconnectedCallback() {
override firstUpdated(changedProperties: PropertyValues<this>) {
super.firstUpdated(changedProperties);
this.renderRoot.append(this.#slot);
this.#slot.addEventListener('slotchange', this.#onSlotchange);
}
override willUpdate(changedProperties: PropertyValues<this>) {
super.willUpdate(changedProperties);
if (changedProperties.has('sources')) {
this.#observeSources();
}
}
override disconnectedCallback() {
super.disconnectedCallback();
this.unobserveSources();
}
override update(changedProperties: PropertyValues<this>) {
super.update(changedProperties);
// we might not need to react to the first slot change
#onSlotchange = () => this.#observeSources();
if (changedProperties.has('sources')) {
this.observeSources();
}
}
observeSources() {
#observeSources() {
const childElements = new Set(this.children);
const elements = this.sources ? document.querySelectorAll(this.sources) : [];
const sourceElements = new Set(elements).union(childElements);
@ -52,8 +61,14 @@ export class FolkBaseSet extends FolkElement {
}
this.sourceElements = sourceElements;
console.log(this.sourceElements);
}
#sourcesCallback = (entry: ClientRectObserverEntry) => {
this.#sourcesMap.set(entry.target, entry.contentRect);
this.requestUpdate();
};
unobserveSources(elements: Set<Element> = this.sourceElements) {
for (const el of elements) {
folkObserver.unobserve(el, this.#sourcesCallback);

View File

@ -34,7 +34,6 @@ export class FolkHull extends FolkBaseSet {
return this.#hull;
}
#slot = document.createElement('slot');
#hullEl = document.createElement('div');
override firstUpdated(changedProperties: PropertyValues<this>): void {
@ -42,22 +41,20 @@ export class FolkHull extends FolkBaseSet {
this.#hullEl.id = 'hull';
this.renderRoot.append(this.#hullEl, this.#slot);
this.#slot.addEventListener('slotchange', this.#onSlotchange);
this.renderRoot.prepend(this.#hullEl);
}
// we might not need to react to the first slot change
#onSlotchange = () => this.observeSources();
override update(changedProperties: PropertyValues<this>) {
super.update(changedProperties);
if (this.sourcesMap.size !== this.sourceElements.size) {
this.style.clipPath = '';
this.style.display = 'none';
return;
}
this.style.display = 'block';
this.#hull = makeHull(this.sourceRects);
this.#hullEl.style.clipPath = verticesToPolygon(this.#hull);
}