// Eryn Wells class Carousel { carousel = null; constructor(element) { this.carousel = element; } } class PhotoParametersTable { tableElement; #makeModelElement; #latitudeElement; #longitudeElement; #megapixelsElement; #widthElement; #heightElement; #isoElement; #focalLengthElement; #fNumberElement; #exposureTimeElement; constructor(element) { this.tableElement = element; } setMakeModel(make, model) { if (!this.#makeModelElement) { this.#makeModelElement = this.#getElementWithQuerySelector("td.make-model"); } if (!this.#makeModelElement) { return; } let makeModel = ""; if (make && model) { return `${make} ${model}`; } else if (make) { return make; } else if (model) { return model; } else { return ""; } this.#makeModelElement.innerHTML = makeModel; } setLocation(latitude, longitude) { let latitudeElement = this.#latitudeElement; if (!latitudeElement) { latitudeElement = this.#getElementWithQuerySelector("td.location > data.latitude"); this.#latitudeElement = latitudeElement; } let longitudeElement = this.#longitudeElement; if (!longitudeElement) { longitudeElement = this.#getElementWithQuerySelector("td.location > data.longitude"); this.#longitudeElement = longitudeElement; } if (!latitudeElement || !longitudeElement) { return; } latitudeElement.innerHTML = latitude; longitudeElement.innerHTML = longitude; } setMegapixels(megapixels) { let megapixelsElement = this.#megapixelsElement; if (!megapixelsElement) { megapixelsElement = this.#getElementWithQuerySelector("td.size > data.megapixels"); this.#megapixelsElement = megapixelsElement; } if (!megapixelsElement) { return; } megapixelsElement.innerHTML = megapixels; } setSize(width, height) { let widthElement = this.#widthElement; if (!widthElement) { widthElement = this.#getElementWithQuerySelector("td.size > data.width"); this.#widthElement = widthElement; } let heightElement = this.#heightElement; if (heightElement) { heightElement = this.#getElementWithQuerySelector("td.size > data.height"); this.#heightElement = heightElement; } if (!widthElement || !heightElement) { return; } widthElement.innerHTML = width; heightElement.innerHTML = height; } setISO(iso) { let isoElement = this.#isoElement; if (!isoElement) { isoElement = this.#getElementWithQuerySelector("td.iso"); this.#isoElement = isoElement; } if (!isoElement) { return; } isoElement.innerHTML = `ISO ${iso}`; } setFocalLength(focalLength) { let focalLengthElement = this.#focalLengthElement; if (!focalLengthElement) { focalLengthElement = this.#getElementWithQuerySelector("td.focal-length"); this.#focalLengthElement = focalLengthElement; } if (!focalLengthElement) { return; } focalLengthElement.innerHTML = `${focalLength} mm`; } setFNumber(f) { let fNumberElement = this.#fNumberElement; if (!fNumberElement) { fNumberElement = this.#getElementWithQuerySelector("td.f-number"); this.#fNumberElement = fNumberElement; } if (!fNumberElement) { return; } fNumberElement.innerHTML = `ƒ${f}`; } setExposureTime(exposureTime) { let exposureTimeElement = this.#exposureTimeElement; if (!exposureTimeElement) { exposureTimeElement = this.#getElementWithQuerySelector("td.exposure-time"); this.#exposureTimeElement = exposureTimeElement; } if (!exposureTimeElement) { return; } exposureTimeElement.innerHTML = `${exposureTime} s`; } #getElementWithQuerySelector(query) { const element = this.tableElement.querySelector(query); if (!element) { console.error(`Couldn't find ${query} element in`, this.tableElement); return null; } return element; } } document.addEventListener("DOMContentLoaded", (event) => { let photoParams = null; const photoParamsTableElement = document.querySelector(".photo-params table"); if (photoParamsTableElement) { photoParams = new PhotoParametersTable(photoParamsTableElement); } document.querySelectorAll("figure.carousel").forEach(carouselElement => { class CarouselItem { element = null; relativeX = 0; isLeftOfContainerCenter = false; constructor(element, relativeX) { this.element = element; this.relativeX = relativeX } get relativeMaxX() { const rect = this.element.getBoundingClientRect(); return this.relativeX + rect.width; } get title() { return this.element.dataset.title; } get latitude() { return this.element.dataset.latitude; } get longitude() { return this.element.dataset.longitude; } get megapixels() { return this.element.dataset.megapixels; } get width() { return this.element.dataset.width; } get height() { return this.element.dataset.height; } get make() { return this.element.dataset.make; } get model() { return this.element.dataset.model; } get iso() { return this.element.dataset.iso; } get focalLength() { return this.element.dataset.focalLength; } get fNumber() { return this.element.dataset.fNumber; } get exposureTime() { return this.element.dataset.exposureTime; } } let captionElement = carouselElement.querySelector("figcaption"); let carouselRect = carouselElement.getBoundingClientRect(); let carouselRectHorizontalCenter = carouselRect.width / 2.0; let carouselItems = Array.from(carouselElement.querySelectorAll("ul > li")).map(item => { let itemRect = item.getClientRects()[0]; let relativeX = itemRect.x - carouselRect.x; console.debug("Item at relative x:", relativeX); return new CarouselItem(item, relativeX); }); let previousTimeoutID = null; let previousScrollLeft = null; let isScrollingLeft = true; carouselElement.querySelector("ul").addEventListener("scroll", event => { if (previousTimeoutID) { clearTimeout(previousTimeoutID); } const target = event.target; const scrollLeft = target.scrollLeft; if (previousScrollLeft === null) { carouselRect = target.getBoundingClientRect(); carouselRectHorizontalCenter = carouselRect.width / 2.0; } if (previousScrollLeft !== null) { isScrollingLeft = scrollLeft > previousScrollLeft; } previousScrollLeft = scrollLeft; console.debug("isScrollingLeft =", isScrollingLeft); carouselItems.forEach(item => { const itemRelativeXCoordinate = isScrollingLeft ? item.relativeX - scrollLeft : item.relativeMaxX - scrollLeft; const itemWasLeftOfContainerCenter = item.isLeftOfContainerCenter; const itemIsLeftOfContainerCenter = itemRelativeXCoordinate < carouselRectHorizontalCenter; item.isLeftOfContainerCenter = itemIsLeftOfContainerCenter; if ( (isScrollingLeft && (!itemWasLeftOfContainerCenter && itemIsLeftOfContainerCenter)) || (!isScrollingLeft && (itemWasLeftOfContainerCenter && !itemIsLeftOfContainerCenter))) { console.debug("Item crossed container center", item); if (captionElement) { captionElement.innerHTML = item.title; } photoParams.setMakeModel(item.make, item.model); photoParams.setLocation(item.latitude, item.longitude); photoParams.setMegapixels(item.megapixels); photoParams.setSize(item.width, item.height); photoParams.setISO(item.iso); photoParams.setFocalLength(item.focalLength); photoParams.setFNumber(item.fNumber); photoParams.setExposureTime(item.exposureTime); } }); previousTimeoutID = setTimeout(() => { console.debug(carouselItems); previousScrollLeft = null; }, 500); }); }); });