Add a JavaScript file for the photos list

This commit is contained in:
Eryn Wells 2023-04-05 08:16:44 -07:00
parent ad9f83ed39
commit da994bd6b7
2 changed files with 117 additions and 0 deletions

View file

@ -0,0 +1,111 @@
// Eryn Wells <eryn@erynwells.me>
class Item {
static allItems = [];
element;
#mouseoverRegionOffsets;
#currentRegion = 0;
constructor(element) {
this.element = element;
this.setUpEventHandlers();
element._item = this;
}
get title() {
return this.element.getAttribute("title");
}
get numberOfImages() {
const numberOfImages = this.element.dataset.numberOfImages;
if (typeof numberOfImages === "undefined" || numberOfImages === null) {
return 1;
}
try {
return parseInt(numberOfImages);
} catch (e) {
console.error("Unable to parse data-number-of-images attribute:", numberOfImages);
return 1;
}
}
get mouseoverRegionOffsets() {
let offsets = this.#mouseoverRegionOffsets;
if (!offsets) {
const numberOfImages = this.numberOfImages;
offsets = new Array(numberOfImages);
const rect = this.element.getBoundingClientRect();
const widthOfRegion = rect.width / numberOfImages;
for (let i = 0; i < numberOfImages; i++) {
offsets[i] = i * widthOfRegion;
}
this.#mouseoverRegionOffsets = offsets;
}
return offsets;
}
setUpEventHandlers() {
if (this.numberOfImages <= 1) {
return;
}
this.element.addEventListener("mousemove", event => {
const offsetX = event.offsetX;
let indexOfRegion = -1;
for (let regionOffset of this.mouseoverRegionOffsets) {
if (regionOffset > offsetX) {
break;
}
indexOfRegion += 1;
}
if (indexOfRegion !== this.#currentRegion) {
console.debug(`Mouse moved at ${offsetX}, ${event.offsetY} in cell for '${this.title}' in region ${indexOfRegion}`);
// TODO: Set image to images[indexOfRegion]
this.#currentRegion = indexOfRegion;
}
});
this.element.addEventListener("mouseout", event => {
console.debug(`Mouse left cell for '${this.title}'`);
// TODO: Reset to the first image.
});
}
addToIntersectionObserver(intersectionObserver) {
intersectionObserver.observe(this.element);
}
handleIntersectionObservation(entry, observer) {
if (entry.isIntersecting) {
console.debug(`Cell for ${this.title} entered the viewport`);
} else {
console.debug(`Cell for ${this.title} left the viewport`);
}
}
}
let intersectionObserver;
document.addEventListener("DOMContentLoaded", event => {
intersectionObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
entry.target._item.handleIntersectionObservation(entry, observer);
});
}, { threshold: 0.5 });
Item.allItems = Array.from(document.querySelectorAll(".photos.list > a")).map(cell => {
const item = new Item(cell)
item.addToIntersectionObserver(intersectionObserver);
return item;
});
});

View file

@ -17,3 +17,9 @@
{{ define "footer" }}
{{ partial "footer.html" . }}
{{ end }}
{{ define "scripts" }}
{{- with resources.Get "scripts/photos/list.js" | fingerprint "md5" -}}
<script src="{{ .RelPermalink }}"></script>
{{- end -}}
{{ end }}