From 9e8bc4a1e2361c4a4e4a0657df9cd893acc68682 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sat, 31 May 2025 17:17:49 -0500 Subject: connector communicates with websocket and make slides into class --- src/connector.js | 21 +++++++++++- src/slides.js | 98 ++++++++++++++++++++++++++++++++++---------------------- src/style.css | 2 ++ 3 files changed, 81 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/connector.js b/src/connector.js index 1fa513b..6c557a8 100644 --- a/src/connector.js +++ b/src/connector.js @@ -1,6 +1,24 @@ +import io from "socket.io-client" + class APIConnector { constructor(url) { this.url = url ?? "" + this.socket = io(url) + + this.asset_index = 0 + this.asset = null + this.prevAssets = null + this.nextAssets = null + this.seekCallbacks = [] + + this.socket.on("seek", e => { + this.asset_index = e.asset_index + this.asset = e.asset + this.prevAssets = e.prev_assets + this.nextAssets = e.next_assets + for (const cb of this.seekCallbacks) + cb() + }) } #fetch(endpoint) { @@ -23,7 +41,8 @@ class APIConnector { } seek(increment) { - return this.fetch(`/seek?increment=${increment}`) + //return this.fetch(`/seek?increment=${increment}`) + this.socket.emit("seek", increment) } fetchAlbums() { diff --git a/src/slides.js b/src/slides.js index 8b4080f..94af74e 100644 --- a/src/slides.js +++ b/src/slides.js @@ -2,17 +2,57 @@ const Flickity = require("flickity") import "flickity/dist/flickity.min.css" import apiConnector from "./connector.js" -export default function initSlides(slidesContainer) { +class Slides { + constructor(slidesContainer) { + /* previous selected index */ + this.selectedIndex = 0 + + this.slidesContainer = slidesContainer + + /* initialize slides */ + this.flickity = new Flickity("#slideshow-carousel", { + wrapAround: true, + prevNextButtons: false, + pageDots: false, + resize: true, + setGallerySize: false, + }) + + this.flickity.on("scroll", progress => { this.scroll(progress) }) + this.flickity.on("staticClick", (e, pointer, cellElement, cellIndex) => { this.staticClick(e, pointer, cellElement, cellIndex) }) + this.flickity.on("dragEnd", () => { this.seek() }) + this.initImages() + + /* initialize seek buttons */ + const seekPrevButton = this.slidesContainer.querySelector("#prevSlide") + const seekNextButton = this.slidesContainer.querySelector("#nextSlide") + + seekPrevButton.addEventListener("click", () => { this.flickity.previous() ; this.seek() }) + seekNextButton.addEventListener("click", () => { this.flickity.next() ; this.seek() }) + } + + seek() { + // this is just like calculating movement in lazycachelist.py + // gets the min of the absolute values and returns signed value + const increment = [ + this.flickity.selectedIndex - this.selectedIndex, // no list wrap + this.flickity.selectedIndex - this.flickity.cells.length, // wrap backwards (0 -> -1) + this.flickity.cells.length - this.selectedIndex, // wrap forwards (-1 -> 0) + ].reduce((key, v) => Math.abs(v) < Math.abs(key) ? v : key) + this.selectedIndex = this.flickity.selectedIndex + apiConnector.seek(increment) + } + /* Flickity function for scrolling to ensure next and prev pics are always * visible and to transition between states */ - function scroll(progress) { - const normalizedProgress = progress / (1 / (flkty.cells.length-1)) + scroll(progress) { + const normalizedProgress = progress / (1 / (this.flickity.cells.length-1)) const liveSelectedIndex = Math.round(normalizedProgress) const localizedProgress = normalizedProgress - liveSelectedIndex - const prevSelectedCell = flkty.cells.at(liveSelectedIndex-1).element - const liveSelectedCell = flkty.cells.at(liveSelectedIndex % flkty.cells.length).element - const nextSelectedCell = flkty.cells.at((liveSelectedIndex+1) % flkty.cells.length).element + const prevSelectedCell = this.flickity.cells.at((liveSelectedIndex-1) % this.flickity.cells.length).element + const liveSelectedCell = this.flickity.cells.at((liveSelectedIndex ) % this.flickity.cells.length).element + const nextSelectedCell = this.flickity.cells.at((liveSelectedIndex+1) % this.flickity.cells.length).element const prevSelectedImage = prevSelectedCell.firstElementChild const liveSelectedImage = liveSelectedCell.firstElementChild @@ -28,52 +68,32 @@ export default function initSlides(slidesContainer) { } /* jump to clicked on slide */ - function staticClick(e, pointer, cellElement, cellIndex) { - flkty.select(cellIndex) + staticClick(e, pointer, cellElement, cellIndex) { + this.flickity.select(cellIndex) + this.seek() } /* make sure images have correct margin when loaded since scroll function * depends on them being loaded */ - function positionImageStatic(img) { + positionImageStatic(img) { const i = parseInt(img.dataset.index) - if (i == flkty.selectedIndex) + if (i == this.flickity.selectedIndex) img.style.marginLeft = (img.parentElement.clientWidth - img.clientWidth) / 2 + "px" - else if ((i + 1) % flkty.cells.length == flkty.selectedIndex) + else if ((i + 1) % this.flickity.cells.length == this.flickity.selectedIndex) img.style.marginLeft = img.parentElement.clientWidth - img.clientWidth + "px" } - function imageLoaded(e) { positionImageStatic(e.target) } - function initImages() { - const imgs = slidesContainer.querySelectorAll("#slideshow-carousel img") + imageLoaded(e) { this.positionImageStatic(e.target) } + initImages() { + const imgs = this.slidesContainer.querySelectorAll("#slideshow-carousel img") for (let i = 0; i < imgs.length; i++) { const img = imgs[i] img.dataset.index = i - img.addEventListener("load", imageLoaded) + img.addEventListener("load", this.imageLoaded) if (img.complete) - positionImageStatic(img) + this.positionImageStatic(img) } } - - /* initialize slides */ - const flkty = new Flickity('#slideshow-carousel', { - wrapAround: true, - prevNextButtons: false, - pageDots: false, - resize: true, - setGallerySize: false, - }) - - flkty.on("scroll", scroll) - flkty.on("staticClick", staticClick) - initImages() - - /* initialize seek buttons */ - const seekPrevButton = slidesContainer.querySelector("#prevSlide") - const seekNextButton = slidesContainer.querySelector("#nextSlide") - - seekPrevButton.addEventListener("click", () => { apiConnector.seek(-1) }) - seekNextButton.addEventListener("click", () => { apiConnector.seek(+1) }) - - /* done */ - return true } + +export default slidesContainer => { new Slides(slidesContainer); return true } diff --git a/src/style.css b/src/style.css index 607e6ec..e84921e 100644 --- a/src/style.css +++ b/src/style.css @@ -94,6 +94,7 @@ svg { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 2.5rem; + max-width: 1366px; margin: auto; padding: 2rem; @@ -111,6 +112,7 @@ svg { #albums-container { grid-template-columns: 1fr 1fr; gap: 1.5rem; + width: 100%; .album-info { font-size-adjust: .4; } } } -- cgit v1.2.3