import ImageTagHelper from "../../core/ImageTagHelper.js"; import ScrollHelper from "../../core/ScrollHelper.js"; import TemplateControl from "../../core/TemplateControl.js"; import { XNode } from "../../core/XNode.js"; const getThumbnail = (iterator: HTMLElement) => { if (iterator.tagName !== "IMG") { iterator = iterator.querySelector("img"); } if(!iterator) { return; } const { thumb } = ImageTagHelper.getUrls(iterator); return thumb; } let i = 1; class ImageGallery extends TemplateControl { current: HTMLElement; indicator: HTMLElement; canvas: HTMLElement; intersectionObserver: IntersectionObserver; root: ShadowRoot; connectedCallback() { this.intersectionObserver = new IntersectionObserver((entries) => { try { let max = null as IntersectionObserverEntry; for (const element of entries) { if (element.isIntersecting) { if (max === null) { max = element; } else { if (max.intersectionRatio < element.intersectionRatio) { max = element; } } } } if (max) { setTimeout(() => { // update the selected index... const index = max.target.getAttribute("item-index"); if (index) { const t = this.root.querySelector(`[item-thumbnail-index="${index}"]`); ScrollHelper.bringIntoView(t as any, false); } }, 1000); } } catch (error) { console.error(error); } }, { threshold: 0.8, root: this }); super.connectedCallback(); } async onAfterConnected() { const { children } = this; for (let index = 0; index < children.length; index++) { const element = children[index]; this.intersectionObserver.observe(element); } } disconnectedCallback() { super.disconnectedCallback(); this.intersectionObserver.disconnect(); } async prepare() { const root = this.attachShadow({ mode: "open", slotAssignment: "manual"}) this.root = root; XNode.render(root,
); const indicator = root.querySelector(`[part="indicator"]`) as HTMLElement; this.indicator = indicator; const canvas = root.querySelector(`[part="canvas"]`) as HTMLElement; this.canvas = canvas; setTimeout(() => this.updateStyle(false), 1000); } onChildAdded(iterator: HTMLElement) { if (!this.current) { this.current = iterator; } const index = i++ + ""; const name = `child${index}`; const { canvas, indicator } = this; const child: XNode = ; const slot = child.appendTo(canvas) as HTMLSlotElement; slot.assign(iterator); iterator.setAttribute("item-index", index); this.intersectionObserver.observe(iterator); const src = getThumbnail(iterator); XNode.render(indicator,
this.thumbnailClick(e, iterator)}>
); } onChildRemoved(child: HTMLElement) { this.intersectionObserver.unobserve(child); } thumbnailClick(e: Event, img: HTMLElement) { this.current = img; this.updateStyle(); } moveLeft() { const previous = this.current.previousElementSibling as HTMLElement; if (!previous) { return; } this.current = previous; this.updateStyle(); } moveRight() { const next = this.current.nextElementSibling as HTMLElement; if (!next) { return; } this.current = next; this.updateStyle(); } updateStyle(useNative = true) { if (!this.current) { return; } ScrollHelper.bringIntoView(this.current, useNative); // const index = Array.from(this.children).indexOf(this.current); // Array.from(this.indicator.children).forEach((x, i) => { // if (i === index) { // setTimeout(() => ScrollHelper.bringIntoView(x as any, useNative), 1000); // } // x.setAttribute("part", i === index // ? "thumbnail active" // : "thumbnail"); // }); } } customElements.define("image-gallery", ImageGallery);