summaryrefslogtreecommitdiff
path: root/static/src/slides.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/src/slides.js')
m---------static6
-rw-r--r--static/src/slides.js137
2 files changed, 137 insertions, 6 deletions
diff --git a/static b/static
deleted file mode 160000
-Subproject 51be71d8943f6e5e0c4b28358f227860c73d53a
diff --git a/static/src/slides.js b/static/src/slides.js
new file mode 100644
index 0000000..e4f6406
--- /dev/null
+++ b/static/src/slides.js
@@ -0,0 +1,137 @@
+const Flickity = require("flickity")
+import "flickity/dist/flickity.min.css"
+import apiConnector from "./connector.js"
+
+class Slides {
+ constructor(slidesContainer) {
+ /* previous selected index */
+ this.selectedIndex = 0
+ this.assetIndex = 0
+
+ this.slidesContainer = slidesContainer
+
+ /* append 11 cells to carousel */
+ const carousel = this.slidesContainer.querySelector("#slideshow-carousel")
+ const cellTemplate = this.slidesContainer.querySelector("#carousel-cell-template")
+ this.cells = []
+ for (let i = 0; i < 11; i++)
+ carousel.appendChild(cellTemplate.content.cloneNode(true))
+
+ /* initialize slides */
+ this.flickity = new Flickity(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("#prev-slide")
+ const seekNextButton = this.slidesContainer.querySelector("#next-slide")
+
+ seekPrevButton.addEventListener("click", () => { this.flickity.previous() ; this.seek() })
+ seekNextButton.addEventListener("click", () => { this.flickity.next() ; this.seek() })
+
+ /* initialize seek callback */
+ apiConnector.seekCallbacks.push(c => { this.seekCallback() })
+
+ /* initialize top controls */
+ const assetDownloadButton = this.slidesContainer.querySelector("#download")
+
+ assetDownloadButton.addEventListener("click", () => { apiConnector.assetDownload(apiConnector.currentAsset) })
+ }
+
+ 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
+ this.assetIndex += increment
+ apiConnector.seek(increment)
+ }
+
+ seekCallback() {
+ let i
+ if (this.assetIndex !== apiConnector.assetIndex) {
+ this.assetIndex = apiConnector.assetIndex
+ i = apiConnector.movement
+
+ for (; i > 0; i--) this.flickity.next()
+ for (; i < 0; i++) this.flickity.previous()
+ this.selectedIndex = this.flickity.selectedIndex
+ }
+
+ // load new imgs
+ // TODO need to make the 11 cells a constant somehow
+ for (i = 0; i < this.flickity.cells.length; i++) {
+ const x = (i + this.selectedIndex + 6) % this.flickity.cells.length
+ const e = this.flickity.cells[x].element
+ const img = e.firstElementChild
+ img.src = apiConnector.assetPreviewSrc(apiConnector.assets[i])
+ }
+ }
+
+ /* Flickity function for scrolling to ensure next and prev pics are always
+ * visible and to transition between states */
+ scroll(progress) {
+ const normalizedProgress = progress / (1 / (this.flickity.cells.length-1))
+ const liveSelectedIndex = Math.round(normalizedProgress)
+ const localizedProgress = normalizedProgress - liveSelectedIndex
+
+ 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
+ const nextSelectedImage = nextSelectedCell.firstElementChild
+
+ const prevMargin = prevSelectedCell.clientWidth - prevSelectedImage.clientWidth
+ const liveMargin = liveSelectedCell.clientWidth - liveSelectedImage.clientWidth
+ const nextMargin = nextSelectedCell.clientWidth - nextSelectedImage.clientWidth
+
+ liveSelectedImage.style.marginLeft = liveMargin / 2 + "px"
+ nextSelectedImage.style.marginLeft = Math.max(0, Math.min(nextMargin, nextMargin * (localizedProgress))) + "px"
+ prevSelectedImage.style.marginLeft = prevMargin - Math.max(0, Math.min(prevMargin, prevMargin * localizedProgress * -1)) + "px" // TODO clean this
+ }
+
+ /* jump to clicked on slide */
+ 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 */
+ positionImageStatic(img) {
+ const i = parseInt(img.dataset.index)
+ if (i == this.flickity.selectedIndex)
+ img.style.marginLeft = (img.parentElement.clientWidth - img.clientWidth) / 2 + "px"
+ else if ((i + 1) % this.flickity.cells.length == this.flickity.selectedIndex)
+ img.style.marginLeft = img.parentElement.clientWidth - img.clientWidth + "px"
+ }
+
+ 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", e => { this.imageLoaded(e) })
+ if (img.complete)
+ this.positionImageStatic(img)
+ }
+ }
+}
+
+export default slidesContainer => { new Slides(slidesContainer); return true }