"use strict"; class ImageCarousel { constructor(props) { this.props = props; this.id = this.props.images.join("").replace(/[\s\./]/g, ""); this.state = { showImageIndex: 0, fullscreen: false, }; this.RUN_INTERVAL = 5000; this.props.images.length > 1 && this.run(); this.toggle_fullscreen = this.toggle_fullscreen.bind(this); } run() { const runningInterval = setInterval(() => { let { showImageIndex } = this.state; const { images } = this.props; this.state.showImageIndex = showImageIndex < images.length - 1 ? ++showImageIndex : 0; this.refresh(); }, this.RUN_INTERVAL); obj2htm.registerAsyncSubscription(this.id, function () { clearInterval(runningInterval); }); this.runningInterval = runningInterval; } set_image_index(i) { clearInterval(this.runningInterval); this.state.showImageIndex = i; this.refresh(); } toggle_fullscreen() { this.state.fullscreen = !this.state.fullscreen; document.getElementById(this.id).classList.toggle("fullscreen"); document.body.style.overflow = this.state.fullscreen ? "hidden" : "initial"; if (this.state.fullscreen) { window.addEventListener("keydown", this.toggle_fullscreen); } else { window.removeEventListener("keydown", this.toggle_fullscreen); } } refresh() { obj2htm.subRender(this.render_image(), document.getElementById(this.id + "-img-element"), { mode: "replace", }); obj2htm.subRender(this.render_bullets(), document.getElementById(this.id + "-bullets"), { mode: "replace", }); obj2htm.subRender(this.render_fullscreen_button(), document.getElementById(this.id + "-fullscreen-btn"), { mode: "replace", }); } render_image() { return { tag: "img", id: this.id + "-img-element", property: "image", alt: `image carousel ${this.props.images[this.state.showImageIndex].replace(/\.[A-Za-z]+/, "")}`, src: this.props.images[this.state.showImageIndex], }; } render_bullets() { return this.props.images.length > 1 ? { tag: "div", id: this.id + "-bullets", class: "carousel-bullets", contents: this.props.images.map((_, i) => { const active = this.state.showImageIndex === i; return { tag: "span", class: `bullet ${active ? "active" : ""}`, onclick: this.set_image_index.bind(this, i), }; }), } : { tag: "span" }; } render_fullscreen_button() { return { tag: "button", id: this.id + "-fullscreen-btn", class: `toggle-fullscreen-button ${this.state.fullscreen ? "to-small" : "to-full"}`, contents: this.state.fullscreen ? "▢" : "⛶", onclick: e => { e.stopImmediatePropagation(); this.toggle_fullscreen(); this.refresh(); }, } } render() { return { tag: "div", id: this.id, class: "image-carousel", contents: [ this.render_image(), this.render_bullets(), this.render_fullscreen_button(), ], }; } } module.exports = ImageCarousel;