feat(ipub): make ipub-background containerized into ipub-body

This commit is contained in:
Guz
2025-10-23 15:00:32 -03:00
parent 77631f2a6c
commit 913bbccd0b

View File

@@ -28,49 +28,84 @@ class IPUBBackground extends IPUBElement {
/**
* @private
*/
static #observer = (() => {
/** @type {Map<string, IPUBBackground>} */
const instancesOnScreen = new Map();
document.addEventListener("scroll", () => {
for (const [_, instance] of instancesOnScreen) {
const perc = getPercentageInView(
instance.querySelector("img") || instance,
static #instancesOnScreen = {
/** @type {Map<IPUBBody, Set<IPUBBackground>>} */
map: new Map(),
/**
* @param {IPUBBackground} background
*/
add(background) {
const body = getAncestor(background, IPUBBody.elementName);
if (!body) {
console.error(
`IPUBBackground: ${background.id} does not have a valid ipub-body ancestor`,
);
instance.fade(perc);
return;
}
});
return new IntersectionObserver((entries) =>
entries.forEach((e) => {
let instance = e.target.parentElement;
let set = this.map.get(body);
if (!set) {
set = new Set();
body.addEventListener("scroll", () => {
for (const instance of set.values()) {
const perc = getPercentageInView(
instance.querySelector("img") || instance,
);
instance.fade(perc);
}
});
}
set.add(background);
this.map.set(body, set);
},
/**
* @param {IPUBBackground} background
*/
remove(background) {
const body = getAncestor(background, IPUBBody.elementName);
if (!body) {
console.error(
`IPUBBackground: ${background.id} does not have a valid ipub-body ancestor`,
);
return;
}
if (
instance.tagName.toLowerCase() !==
IPUBBackground.elementName.toLowerCase()
) {
instance = instance.parentElement;
}
const set = this.map.get(body);
if (!set) {
return;
}
if (
instance.tagName.toLowerCase() !==
IPUBBackground.elementName.toLowerCase()
) {
console.error(
"IPUBBackground: malformed <ipub-background> element",
e.target,
);
return;
}
set.delete(background);
if (e.intersectionRatio > 0 && instance.id) {
instancesOnScreen.set(instance.id, instance);
} else if (instance.id) {
instancesOnScreen.delete(instance.id);
}
}),
);
})();
if (set.size === 0) {
this.map.delete(body);
}
},
};
static addToScreen() {}
/**
* @private
*/
static #observer = new IntersectionObserver((entries) => {
for (const { intersectionRatio, target: image } of entries) {
const instance = getAncestor(image, IPUBBackground.elementName);
if (!instance) {
console.error(
"IPUBBackground: malformed <ipub-background> element",
image,
);
return;
}
if (intersectionRatio > 0 && instance.id) {
IPUBBackground.#instancesOnScreen.add(instance);
} else if (instance.id) {
IPUBBackground.#instancesOnScreen.remove(instance);
}
}
});
connectedCallback() {
super.connectedCallback();
@@ -126,8 +161,6 @@ class IPUBBackground extends IPUBElement {
* @returns {void | Promise<void>}
*/
fade(perc) {
console.debug(`IPUBBackground: ${this.id} is ${perc} on screen`);
if (!this.style.getPropertyValue("--ipub-fade")) {
this.style.setProperty("--ipub-fade", `${perc}%`);
return;
@@ -264,7 +297,19 @@ class IPUBInteraction extends IPUBElement {
}
/**
* @param {HTMLElement} el
* @param {string} tagName
* @returns {HTMLElement | undefined}
*/
function getAncestor(el, tagName) {
if (!el.parentElement) {
return undefined;
}
if (el.parentElement.tagName.toLowerCase() === tagName.toLowerCase()) {
return el.parentElement;
}
return getAncestor(el.parentElement, tagName);
}
/**
* @param {Readonly<Element>} el
@@ -330,3 +375,4 @@ function getPercentageInView(element) {
return Math.round((inView / globalThis.innerHeight) * 100);
}