对同一页面上的两个单独的画廊使用灯箱画廊代码?

时间:2019-10-24 03:53:13

标签: javascript jquery html css sass

我有一些很棒的灯箱画廊代码。我只需要一次在一个页面上使用1,但是客户希望在同一页面上包含两个不同的画廊。我尝试了几种方法:

  1. 我尝试做的第一件事就是使用不同的图片将相同的HTML复制/粘贴到不同的div中。那对我没用。

  2. 我做的第二件事是我尝试遍历CSS,将每个单个Gallery类重命名为gallery-two,然后调整我可以在javascript中找到的每个类以匹配其CSS对应类。最终发生的事情是,当我单击第二个画廊时,出现了原始的图片/画廊集,而不是我单击的属于新画廊的照片。

这是原始的灯箱画廊代码:

https://codepen.io/Lancewalker/pen/JjjdbOZ

class AsyncGallery {
    constructor(settings) {
        this.settings = {
            images: ".gallery__Image",
            loop: true,
            next: undefined,
            prev: undefined,
            dots: undefined,
            close: undefined,
            loader: undefined,
            counter: undefined,
            counterDivider: "/",
            keyboardNavigation: true,
            hiddenElements: []
        };

        Object.assign(this.settings, settings);

        this.gallery = null;
        this.index = 0;
        this.items = [...document.querySelectorAll(this.settings.images)];

        this.addedItems = {};

        this.touch = {
            endX: 0,
            startX: 0
        };

        this.init();
    }

    get loading() {
        return !this.settings.hiddenElements.includes("loader");
    }

    get dotsVisible() {
        return !this.settings.hiddenElements.includes("dots");
    }

    init() {
        this.clearUncomplete();
        this.createElements();
        this.bindEvents();
    }

    clearUncomplete() {
        this.items = this.items.filter(item => {
            return item.dataset.large;
        });
    }

    createElements() {
        this.gallery = document.createElement("DIV");
        this.gallery.classList.add("asyncGallery");

        this.createSingleElement({
            element: "prev",
            type: "BUTTON",
            event: "click",
            func: this.getPrevious
        });

        this.createSingleElement({
            element: "next",
            type: "BUTTON",
            event: "click",
            func: this.getNext
        });

        this.createSingleElement({
            element: "close",
            type: "BUTTON",
            event: "click",
            func: this.closeGallery
        });

        this.createSingleElement({
            element: "loader",
            type: "SPAN",
            text: "Loading..."
        });

        this.createSingleElement({
            element: "counter",
            type: "SPAN",
            text: "0/0"
        });

        this.createSingleElement({
            element: "dots",
            type: "UL",
            text: ""
        });

        if (!this.settings.hiddenElements.includes("dots")) {
            this.items.forEach((item, i) => {
                let dot = document.createElement("LI");
                dot.dataset.index = i;
                let button = document.createElement("BUTTON");
                button.innerHTML = i;
                button.addEventListener("click", () => {
                    this.index = i;
                    this.getItem(i);
                });

                dot.append(button);
                this.dots.append(dot);
            });
        }

        window.document.body.append(this.gallery);
    }

    createSingleElement({ element, type, event = "click", func, text }) {
        if (!this.settings.hiddenElements.includes(element)) {
            if (!this.settings[element]) {
                this[element] = document.createElement(type);
                this[element].classList.add(
                    `asyncGallery__${this.capitalizeFirstLetter(element)}`
                );
                this[element].innerHTML = text !== undefined ? text : element;
                this.gallery.append(this[element]);
            } else {
                this[element] = document.querySelector(this.settings[element]);
                this.gallery.append(this[element]);
            }

            if (func) {
                this[element].addEventListener(event, func.bind(this));
            }
        }
    }

    getItem(i, content = null) {
        let contentObj = content;
        if (contentObj === null) {
            contentObj = {};
            contentObj.src = this.items[i].dataset.large;
            contentObj.description = this.items[i].dataset.description;
        }

        if (!this.settings.hiddenElements.includes("counter")) {
            this.counter.innerHTML = `
          <span class="asyncGallery__Current">${this.index + 1}</span>${
                this.settings.counterDivider
                }<span class="asyncGallery__Current">${this.items.length}</span>
          `;
        }

        if (!this.addedItems.hasOwnProperty(i)) {
            let image = document.createElement("IMG");

            let galleryItem = document.createElement("DIV");
            galleryItem.classList.add("asyncGallery__Item");

            if (this.loading) {
                this.loader.classList.add("is-visible");
            }

            this.clearVisible();

            if (this.dotsVisible) {
                this.gallery
                    .querySelector(`.asyncGallery__Dots li[data-index="${i}"]`)
                    .classList.add("is-active");
            }

            image.src = contentObj.src;
            image.alt = contentObj.description ? contentObj.description : "";

            galleryItem.innerHTML = `
          <div class="asyncGallery__ItemImage">
            ${image.outerHTML}
          </div>
          `;

            if (contentObj.description) {
                galleryItem.innerHTML += `
            <div class="asyncGallery__ItemDescription">
              <p>${contentObj.description}</p>
            </div>
            `;
            }

            this.gallery.append(galleryItem);
            this.addedItems[i] = galleryItem;

            image.addEventListener("load", () => {
                this.addedItems[i].loaded = true;
                if (!this.gallery.querySelector(".asyncGallery__Item.is-visible")) {
                    this.addedItems[i].classList.add("is-visible");
                }

                if (this.loading) {
                    this.loader.classList.remove("is-visible");
                }
            });
        } else {
            this.clearVisible();
            if (this.addedItems[this.index].loaded) {
                this.addedItems[this.index].classList.add("is-visible");
                if (this.loading) {
                    this.loader.classList.remove("is-visible");
                }
            } else if (this.loading) {
                this.loader.classList.add("is-visible");
            }

            if (this.dotsVisible) {
                this.gallery
                    .querySelector(`.asyncGallery__Dots li[data-index="${i}"]`)
                    .classList.add("is-active");
            }
        }

        if (!this.settings.loop) {
            if (this.index === 0) this.prev.setAttribute("disabled", true);
            else this.prev.removeAttribute("disabled");

            if (this.index === this.items.length - 1)
                this.next.setAttribute("disabled", true);
            else this.next.removeAttribute("disabled");
        }
    }

    clearVisible() {
        if (this.gallery.querySelector(".asyncGallery__Item.is-visible")) {
            this.gallery
                .querySelector(".asyncGallery__Item.is-visible")
                .classList.remove("is-visible");
        }

        if (this.gallery.querySelector(".asyncGallery__Dots li.is-active")) {
            this.gallery
                .querySelector(".asyncGallery__Dots li.is-active")
                .classList.remove("is-active");
        }
    }

    closeGallery() {
        this.gallery.classList.remove("is-visible");
        this.clearVisible();
    }

    capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
    }

    handleGesure() {
        if (this.touch.endX > this.touch.startX + 20) {
            this.getPrevious();
        } else if (this.touch.endX < this.touch.startX - 20) {
            this.getNext();
        }
    }

    getPrevious() {
        if (this.settings.loop) {
            this.index--;
            if (this.index === -1) {
                this.index = this.items.length - 1;
            }
            this.getItem(this.index);
        } else if (this.index > 0) {
            this.index--;
            this.getItem(this.index);
        }
    }

    getNext() {
        if (this.settings.loop) {
            this.index++;
            if (this.index === this.items.length) {
                this.index = 0;
            }
            this.getItem(this.index);
        } else if (this.index < this.items.length - 1) {
            this.index++;
            this.getItem(this.index);
        }
    }

    bindEvents() {
        this.items.forEach((item, i) => {
            item.addEventListener("click", e => {
                this.gallery.classList.add("is-visible");
                this.index = i;
                this.getItem(i, {
                    src: e.target.dataset.large,
                    description: e.target.dataset.description
                });
            });
        });

        document.addEventListener("keyup", e => {
            if (this.gallery.classList.contains("is-visible")) {
                if (e.key === "Escape") this.closeGallery();
                if (this.settings.keyboardNavigation) {
                    if (e.keyCode === 39) this.getNext();
                    else if (e.keyCode === 37) this.getPrevious();
                }
            }
        });

        this.gallery.addEventListener(
            "touchstart",
            e => {
                this.touch.startX = e.changedTouches[0].screenX;
            },
            false
        );

        this.gallery.addEventListener(
            "touchend",
            e => {
                this.touch.endX = e.changedTouches[0].screenX;
                this.handleGesure();
            },
            false
        );
    }
}

new AsyncGallery();
.ec-container {
  max-width: 98%;
  margin: 1% auto;
}

.gallery {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.gallery div {
  max-width: calc(20% - 20px);
  margin: 10px;
  transition: opacity 200ms;
  cursor: pointer;
}

.gallery div:hover {
  opacity: 0.8;
}

.gallery div img {
  max-width: 100%;
}

.asyncGallery {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
  z-index: 10000;
  visibility: hidden;
  background-color: rgba(30, 30, 30, 0.95);
  transition: opacity 200ms, visibility 200ms;
}

.asyncGallery.is-visible {
  opacity: 1;
  visibility: visible;
}

.asyncGallery__Item {
  position: absolute;
  top: 50%;
  left: 50%;
  opacity: 0;
  visibility: hidden;
  overflow: hidden;
  transform: translate(-50%, -50%);
  transition: opacity 200ms, visibility 200ms;
}

.asyncGallery__Item.is-visible {
  opacity: 1;
  visibility: visible;
}

.asyncGallery__ItemImage img {
  max-height: 80vh;
  display: block;
  max-width: 95vw;
}

.asyncGallery__ItemDescription,
.asyncGallery__Loader {
  color: #fff;
}

.asyncGallery__Loader {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  color: #fff;
  z-index: 100;
}

.asyncGallery__Loader.is-visible {
  display: block;
}

.asyncGallery button {
  background-color: transparent;
  border: 0;
  outline: 0;
  padding: 0;
  font-size: 0;
  cursor: pointer;
}

.asyncGallery__Close {
  position: absolute;
  top: 3%;
  right: 4%;
  width: 30px;
  height: 30px;
  z-index: 1000;
  background-repeat: no-repeat;
  background-size: 30px 30px;
  background-image: url("data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNTEycHgiIHZlcnNpb249IjEuMSIgaGVpZ2h0PSI1MTJweCIgdmlld0JveD0iMCAwIDY0IDY0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2NCA2NCI+CiAgPGc+CiAgICA8cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMjguOTQxLDMxLjc4NkwwLjYxMyw2MC4xMTRjLTAuNzg3LDAuNzg3LTAuNzg3LDIuMDYyLDAsMi44NDljMC4zOTMsMC4zOTQsMC45MDksMC41OSwxLjQyNCwwLjU5ICAgYzAuNTE2LDAsMS4wMzEtMC4xOTYsMS40MjQtMC41OWwyOC41NDEtMjguNTQxbDI4LjU0MSwyOC41NDFjMC4zOTQsMC4zOTQsMC45MDksMC41OSwxLjQyNCwwLjU5YzAuNTE1LDAsMS4wMzEtMC4xOTYsMS40MjQtMC41OSAgIGMwLjc4Ny0wLjc4NywwLjc4Ny0yLjA2MiwwLTIuODQ5TDM1LjA2NCwzMS43ODZMNjMuNDEsMy40MzhjMC43ODctMC43ODcsMC43ODctMi4wNjIsMC0yLjg0OWMtMC43ODctMC43ODYtMi4wNjItMC43ODYtMi44NDgsMCAgIEwzMi4wMDMsMjkuMTVMMy40NDEsMC41OWMtMC43ODctMC43ODYtMi4wNjEtMC43ODYtMi44NDgsMGMtMC43ODcsMC43ODctMC43ODcsMi4wNjIsMCwyLjg0OUwyOC45NDEsMzEuNzg2eiIvPgogIDwvZz4KPC9zdmc+Cg==");
}

.asyncGallery__Counter {
  position: absolute;
  font-size: 20px;
  font-weight: bold;
  color: #fff;
  right: 40px;
  bottom: 40px;
}

.asyncGallery__Dots {
  position: absolute;
  left: 50%;
  bottom: 40px;
  display: flex;
  margin: 0;
  padding: 0;
  transform: translateX(-50%);
  list-style-type: none;
  z-index: 1000;
}

.asyncGallery__Dots button {
  padding: 0;
  width: 10px;
  height: 10px;
  background-color: #fff;
  border: 0;
  outline: 0;
  border-radius: 50%;
}

.asyncGallery__Dots li {
  opacity: 0.2;
  transition: opacity 200ms;
}

.asyncGallery__Dots li + li {
  margin-left: 10px;
}

.asyncGallery__Dots li.is-active {
  opacity: 1;
}

.asyncGallery__Next,
.asyncGallery__Prev {
  position: absolute;
  top: 50%;
  width: 30px;
  height: 30px;
  z-index: 1000;
  transition: transform 200ms, opacity 200ms;
  transform: translateY(-50%);
}

.asyncGallery__Next:disabled,
.asyncGallery__Prev:disabled {
  opacity: 0.2;
  cursor: default;
}

.asyncGallery__Next:before,
.asyncGallery__Prev:before {
  position: absolute;
  content: "";
  top: 50%;
  left: 50%;
  background-image: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129' xmlns:xlink='http://www.w3.org/1999/xlink' enable-background='new 0 0 129 129'%3E%3Cg%3E%3Cpath d='m40.4,121.3c-0.8,0.8-1.8,1.2-2.9,1.2s-2.1-0.4-2.9-1.2c-1.6-1.6-1.6-4.2 0-5.8l51-51-51-51c-1.6-1.6-1.6-4.2 0-5.8 1.6-1.6 4.2-1.6 5.8,0l53.9,53.9c1.6,1.6 1.6,4.2 0,5.8l-53.9,53.9z' fill='%23fff'/%3E%3C/g%3E%3C/svg%3E%0A");
  width: 30px;
  height: 30px;
  background-repeat: no-repeat;
  background-size: 30px 30px;
}

.asyncGallery__Next {
  right: 40px;
}

.asyncGallery__Next:hover {
  transform: translateX(2px) translateY(-50%);
}

.asyncGallery__Next:before {
  transform: translate3d(-50%, -50%, 0);
}

.asyncGallery__Prev {
  left: 40px;
}

.asyncGallery__Prev:hover {
  transform: translateX(-2px) translateY(-50%);
}

.asyncGallery__Prev:before {
  transform: translate3d(-50%, -50%, 0) scale(-1);
}

@media screen and (max-width: 800px) {
  .gallery img {
    max-width: calc(50% - 40px);
    margin: 20px;
    transition: opacity 200ms;
    cursor: pointer;
  }

  .gallery-no-lb-2-items div {
    max-width: 90%;
    margin: 20px;
  }

  .asyncGallery__Dots {
    bottom: 15px;
  }

  .asyncGallery__Counter {
    right: 15px;
    bottom: 15px;
    font-size: 12px;
  }

  .asyncGallery__Item {
    width: 100%;
  }

  .asyncGallery__ItemImage img {
    max-height: none;
    max-width: 100%;
  }

  .asyncGallery__ItemDescription {
    padding: 0 20px;
  }

  .asyncGallery__Next,
  .asyncGallery__Prev {
    display: none;
  }

  .gallery {
    display: inline-flex;
  }

  .gallery div {
    max-width: 90%;
    margin: 10px auto;
  }

  .gallery div img {
    max-width: 100%;
    margin: 0 auto;
  }
<div class="ec-container" id="project-ec">
    <div class="gallery">
        <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I8950.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I8950.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 1">
        </div>

        <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89502.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89502.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 2">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89503.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89503.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 3">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89504.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89504.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 4">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89505.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89505.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 5">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89506.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89506.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 6">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89507.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89507.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 7">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89508.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89508.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 8">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I89509.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I89509.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 9">
        </div>        <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895010.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895010.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 10">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895011.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895011.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 11">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895021.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895021.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 12">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895013.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895013.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 13">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895014.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895014.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 14">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895022.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895022.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 15">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895016.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895016.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 16">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895017.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895017.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 17">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895018.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895018.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 18">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895019.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895019.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 19">
        </div>
              <div>
            <img class="gallery__Image" src="https://www.lancewalker.life/images/ec/AL4I895020.jpg" data-description=""
                 data-large="https://www.lancewalker.life/images/ec/AL4I895020.jpg" alt="Eagle Class 53 - FAST FORWARD COMPOSITES Gallery Image 20">
        </div>		
    </div>
</div>

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我创建了一个新设置,您可以在其中设置画廊内容:

this.settings = {
    myGallery: "gallery_1", // add this
    images: ".gallery__Image",
    loop: true,
    next: undefined,
    prev: undefined,
    dots: undefined,
    close: undefined,
    loader: undefined,
    counter: undefined,
    counterDivider: "/",
    keyboardNavigation: true,
    hiddenElements: []
};

之后,我更改了以下代码行:

this.gallery = document.getElementById(this.settings.myGallery);
this.items = [...this.gallery.querySelectorAll(this.settings.images)];

要在图库中说,它只需要提取myGallery内容中的项目即可。

现在,您可以创建画廊的不同距离,只需更改我添加的新设置(在本示例中,我创建了一个循环以在project-ec块中启动每个画廊。每个画廊都必须有一个ID和一个类gallery。):

var allTags = document.getElementById('project-ec').getElementsByClassName("gallery");

for (var i = 0, len = allTags.length; i < len; i++) {
  new AsyncGallery({
    myGallery: String(allTags[i].id)
  }); 
}

如果您不能将画廊放在同一个街区中,或者对您来说更简单,则也可以手动启动每个画廊(默认情况下,如果您未编写任何设置,系统会搜索名为{ {1}}):

gallery_1

正在执行的代码:

new AsyncGallery();

new AsyncGallery({
  myGallery:"gallery_2"
});
class AsyncGallery {
    constructor(settings) {
        this.settings = {
            myGallery: "gallery_1", 
            images: ".gallery__Image",
            loop: true,
            next: undefined,
            prev: undefined,
            dots: undefined,
            close: undefined,
            loader: undefined,
            counter: undefined,
            counterDivider: "/",
            keyboardNavigation: true,
            hiddenElements: []
        };

        Object.assign(this.settings, settings);

        this.gallery = document.getElementById(this.settings.myGallery);
        this.index = 0;
        this.items = [...this.gallery.querySelectorAll(this.settings.images)];

        this.addedItems = {};

        this.touch = {
            endX: 0,
            startX: 0
        };

        this.init();
    }

    get loading() {
        return !this.settings.hiddenElements.includes("loader");
    }

    get dotsVisible() {
        return !this.settings.hiddenElements.includes("dots");
    }

    init() {
        this.clearUncomplete();
        this.createElements();
        this.bindEvents();
    }

    clearUncomplete() {
        this.items = this.items.filter(item => {
            return item.dataset.large;
        });
    }

    createElements() {
        this.gallery = document.createElement("DIV");
        this.gallery.classList.add("asyncGallery");

        this.createSingleElement({
            element: "prev",
            type: "BUTTON",
            event: "click",
            func: this.getPrevious
        });

        this.createSingleElement({
            element: "next",
            type: "BUTTON",
            event: "click",
            func: this.getNext
        });

        this.createSingleElement({
            element: "close",
            type: "BUTTON",
            event: "click",
            func: this.closeGallery
        });

        this.createSingleElement({
            element: "loader",
            type: "SPAN",
            text: "Loading..."
        });

        this.createSingleElement({
            element: "counter",
            type: "SPAN",
            text: "0/0"
        });

        this.createSingleElement({
            element: "dots",
            type: "UL",
            text: ""
        });

        if (!this.settings.hiddenElements.includes("dots")) {
            this.items.forEach((item, i) => {
                let dot = document.createElement("LI");
                dot.dataset.index = i;
                let button = document.createElement("BUTTON");
                button.innerHTML = i;
                button.addEventListener("click", () => {
                    this.index = i;
                    this.getItem(i);
                });

                dot.append(button);
                this.dots.append(dot);
            });
        }

        window.document.body.append(this.gallery);
    }

    createSingleElement({ element, type, event = "click", func, text }) {
        if (!this.settings.hiddenElements.includes(element)) {
            if (!this.settings[element]) {
                this[element] = document.createElement(type);
                this[element].classList.add(
                    `asyncGallery__${this.capitalizeFirstLetter(element)}`
                );
                this[element].innerHTML = text !== undefined ? text : element;
                this.gallery.append(this[element]);
            } else {
                this[element] = document.querySelector(this.settings[element]);
                this.gallery.append(this[element]);
            }

            if (func) {
                this[element].addEventListener(event, func.bind(this));
            }
        }
    }

    getItem(i, content = null) {
        let contentObj = content;
        if (contentObj === null) {
            contentObj = {};
            contentObj.src = this.items[i].dataset.large;
            contentObj.description = this.items[i].dataset.description;
        }

        if (!this.settings.hiddenElements.includes("counter")) {
            this.counter.innerHTML = `
          <span class="asyncGallery__Current">${this.index + 1}</span>${
                this.settings.counterDivider
                }<span class="asyncGallery__Current">${this.items.length}</span>
          `;
        }

        if (!this.addedItems.hasOwnProperty(i)) {
            let image = document.createElement("IMG");

            let galleryItem = document.createElement("DIV");
            galleryItem.classList.add("asyncGallery__Item");

            if (this.loading) {
                this.loader.classList.add("is-visible");
            }

            this.clearVisible();

            if (this.dotsVisible) {
                this.gallery
                    .querySelector(`.asyncGallery__Dots li[data-index="${i}"]`)
                    .classList.add("is-active");
            }

            image.src = contentObj.src;
            image.alt = contentObj.description ? contentObj.description : "";

            galleryItem.innerHTML = `
          <div class="asyncGallery__ItemImage">
            ${image.outerHTML}
          </div>
          `;

            if (contentObj.description) {
                galleryItem.innerHTML += `
            <div class="asyncGallery__ItemDescription">
              <p>${contentObj.description}</p>
            </div>
            `;
            }

            this.gallery.append(galleryItem);
            this.addedItems[i] = galleryItem;

            image.addEventListener("load", () => {
                this.addedItems[i].loaded = true;
                if (!this.gallery.querySelector(".asyncGallery__Item.is-visible")) {
                    this.addedItems[i].classList.add("is-visible");
                }

                if (this.loading) {
                    this.loader.classList.remove("is-visible");
                }
            });
        } else {
            this.clearVisible();
            if (this.addedItems[this.index].loaded) {
                this.addedItems[this.index].classList.add("is-visible");
                if (this.loading) {
                    this.loader.classList.remove("is-visible");
                }
            } else if (this.loading) {
                this.loader.classList.add("is-visible");
            }

            if (this.dotsVisible) {
                this.gallery
                    .querySelector(`.asyncGallery__Dots li[data-index="${i}"]`)
                    .classList.add("is-active");
            }
        }

        if (!this.settings.loop) {
            if (this.index === 0) this.prev.setAttribute("disabled", true);
            else this.prev.removeAttribute("disabled");

            if (this.index === this.items.length - 1)
                this.next.setAttribute("disabled", true);
            else this.next.removeAttribute("disabled");
        }
    }

    clearVisible() {
        if (this.gallery.querySelector(".asyncGallery__Item.is-visible")) {
            this.gallery
                .querySelector(".asyncGallery__Item.is-visible")
                .classList.remove("is-visible");
        }

        if (this.gallery.querySelector(".asyncGallery__Dots li.is-active")) {
            this.gallery
                .querySelector(".asyncGallery__Dots li.is-active")
                .classList.remove("is-active");
        }
    }

    closeGallery() {
        this.gallery.classList.remove("is-visible");
        this.clearVisible();
    }

    capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
    }

    handleGesure() {
        if (this.touch.endX > this.touch.startX + 20) {
            this.getPrevious();
        } else if (this.touch.endX < this.touch.startX - 20) {
            this.getNext();
        }
    }

    getPrevious() {
        if (this.settings.loop) {
            this.index--;
            if (this.index === -1) {
                this.index = this.items.length - 1;
            }
            this.getItem(this.index);
        } else if (this.index > 0) {
            this.index--;
            this.getItem(this.index);
        }
    }

    getNext() {
        if (this.settings.loop) {
            this.index++;
            if (this.index === this.items.length) {
                this.index = 0;
            }
            this.getItem(this.index);
        } else if (this.index < this.items.length - 1) {
            this.index++;
            this.getItem(this.index);
        }
    }

    bindEvents() {
        this.items.forEach((item, i) => {
            item.addEventListener("click", e => {
                this.gallery.classList.add("is-visible");
                this.index = i;
                this.getItem(i, {
                    src: e.target.dataset.large,
                    description: e.target.dataset.description
                });
            });
        });

        document.addEventListener("keyup", e => {
            if (this.gallery.classList.contains("is-visible")) {
                if (e.key === "Escape") this.closeGallery();
                if (this.settings.keyboardNavigation) {
                    if (e.keyCode === 39) this.getNext();
                    else if (e.keyCode === 37) this.getPrevious();
                }
            }
        });

        this.gallery.addEventListener(
            "touchstart",
            e => {
                this.touch.startX = e.changedTouches[0].screenX;
            },
            false
        );

        this.gallery.addEventListener(
            "touchend",
            e => {
                this.touch.endX = e.changedTouches[0].screenX;
                this.handleGesure();
            },
            false
        );
    }
}

var allTags = document.getElementById('project-ec').getElementsByClassName("gallery");

for (var i = 0, len = allTags.length; i < len; i++) {
  new AsyncGallery({
    myGallery: String(allTags[i].id)
  }); 
}
.ec-container {
  max-width: 98%;
  margin: 1% auto;
}

.gallery {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.gallery div {
  max-width: calc(20% - 20px);
  margin: 10px;
  transition: opacity 200ms;
  cursor: pointer;
}

.gallery div:hover {
  opacity: 0.8;
}

.gallery div img {
  max-width: 100%;
}

.asyncGallery {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
  z-index: 10000;
  visibility: hidden;
  background-color: rgba(30, 30, 30, 0.95);
  transition: opacity 200ms, visibility 200ms;
}

.asyncGallery.is-visible {
  opacity: 1;
  visibility: visible;
}

.asyncGallery__Item {
  position: absolute;
  top: 50%;
  left: 50%;
  opacity: 0;
  visibility: hidden;
  overflow: hidden;
  transform: translate(-50%, -50%);
  transition: opacity 200ms, visibility 200ms;
}

.asyncGallery__Item.is-visible {
  opacity: 1;
  visibility: visible;
}

.asyncGallery__ItemImage img {
  max-height: 80vh;
  display: block;
  max-width: 95vw;
}

.asyncGallery__ItemDescription,
.asyncGallery__Loader {
  color: #fff;
}

.asyncGallery__Loader {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
  color: #fff;
  z-index: 100;
}

.asyncGallery__Loader.is-visible {
  display: block;
}

.asyncGallery button {
  background-color: transparent;
  border: 0;
  outline: 0;
  padding: 0;
  font-size: 0;
  cursor: pointer;
}

.asyncGallery__Close {
  position: absolute;
  top: 3%;
  right: 4%;
  width: 30px;
  height: 30px;
  z-index: 1000;
  background-repeat: no-repeat;
  background-size: 30px 30px;
  background-image: url("data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNTEycHgiIHZlcnNpb249IjEuMSIgaGVpZ2h0PSI1MTJweCIgdmlld0JveD0iMCAwIDY0IDY0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2NCA2NCI+CiAgPGc+CiAgICA8cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMjguOTQxLDMxLjc4NkwwLjYxMyw2MC4xMTRjLTAuNzg3LDAuNzg3LTAuNzg3LDIuMDYyLDAsMi44NDljMC4zOTMsMC4zOTQsMC45MDksMC41OSwxLjQyNCwwLjU5ICAgYzAuNTE2LDAsMS4wMzEtMC4xOTYsMS40MjQtMC41OWwyOC41NDEtMjguNTQxbDI4LjU0MSwyOC41NDFjMC4zOTQsMC4zOTQsMC45MDksMC41OSwxLjQyNCwwLjU5YzAuNTE1LDAsMS4wMzEtMC4xOTYsMS40MjQtMC41OSAgIGMwLjc4Ny0wLjc4NywwLjc4Ny0yLjA2MiwwLTIuODQ5TDM1LjA2NCwzMS43ODZMNjMuNDEsMy40MzhjMC43ODctMC43ODcsMC43ODctMi4wNjIsMC0yLjg0OWMtMC43ODctMC43ODYtMi4wNjItMC43ODYtMi44NDgsMCAgIEwzMi4wMDMsMjkuMTVMMy40NDEsMC41OWMtMC43ODctMC43ODYtMi4wNjEtMC43ODYtMi44NDgsMGMtMC43ODcsMC43ODctMC43ODcsMi4wNjIsMCwyLjg0OUwyOC45NDEsMzEuNzg2eiIvPgogIDwvZz4KPC9zdmc+Cg==");
}

.asyncGallery__Counter {
  position: absolute;
  font-size: 20px;
  font-weight: bold;
  color: #fff;
  right: 40px;
  bottom: 40px;
}

.asyncGallery__Dots {
  position: absolute;
  left: 50%;
  bottom: 40px;
  display: flex;
  margin: 0;
  padding: 0;
  transform: translateX(-50%);
  list-style-type: none;
  z-index: 1000;
}

.asyncGallery__Dots button {
  padding: 0;
  width: 10px;
  height: 10px;
  background-color: #fff;
  border: 0;
  outline: 0;
  border-radius: 50%;
}

.asyncGallery__Dots li {
  opacity: 0.2;
  transition: opacity 200ms;
}

.asyncGallery__Dots li + li {
  margin-left: 10px;
}

.asyncGallery__Dots li.is-active {
  opacity: 1;
}

.asyncGallery__Next,
.asyncGallery__Prev {
  position: absolute;
  top: 50%;
  width: 30px;
  height: 30px;
  z-index: 1000;
  transition: transform 200ms, opacity 200ms;
  transform: translateY(-50%);
}

.asyncGallery__Next:disabled,
.asyncGallery__Prev:disabled {
  opacity: 0.2;
  cursor: default;
}

.asyncGallery__Next:before,
.asyncGallery__Prev:before {
  position: absolute;
  content: "";
  top: 50%;
  left: 50%;
  background-image: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129' xmlns:xlink='http://www.w3.org/1999/xlink' enable-background='new 0 0 129 129'%3E%3Cg%3E%3Cpath d='m40.4,121.3c-0.8,0.8-1.8,1.2-2.9,1.2s-2.1-0.4-2.9-1.2c-1.6-1.6-1.6-4.2 0-5.8l51-51-51-51c-1.6-1.6-1.6-4.2 0-5.8 1.6-1.6 4.2-1.6 5.8,0l53.9,53.9c1.6,1.6 1.6,4.2 0,5.8l-53.9,53.9z' fill='%23fff'/%3E%3C/g%3E%3C/svg%3E%0A");
  width: 30px;
  height: 30px;
  background-repeat: no-repeat;
  background-size: 30px 30px;
}

.asyncGallery__Next {
  right: 40px;
}

.asyncGallery__Next:hover {
  transform: translateX(2px) translateY(-50%);
}

.asyncGallery__Next:before {
  transform: translate3d(-50%, -50%, 0);
}

.asyncGallery__Prev {
  left: 40px;
}

.asyncGallery__Prev:hover {
  transform: translateX(-2px) translateY(-50%);
}

.asyncGallery__Prev:before {
  transform: translate3d(-50%, -50%, 0) scale(-1);
}

@media screen and (max-width: 800px) {
  .gallery img {
    max-width: calc(50% - 40px);
    margin: 20px;
    transition: opacity 200ms;
    cursor: pointer;
  }

  .gallery-no-lb-2-items div {
    max-width: 90%;
    margin: 20px;
  }

  .asyncGallery__Dots {
    bottom: 15px;
  }

  .asyncGallery__Counter {
    right: 15px;
    bottom: 15px;
    font-size: 12px;
  }

  .asyncGallery__Item {
    width: 100%;
  }

  .asyncGallery__ItemImage img {
    max-height: none;
    max-width: 100%;
  }

  .asyncGallery__ItemDescription {
    padding: 0 20px;
  }

  .asyncGallery__Next,
  .asyncGallery__Prev {
    display: none;
  }

  .gallery {
    display: inline-flex;
  }

  .gallery div {
    max-width: 90%;
    margin: 10px auto;
  }

  .gallery div img {
    max-width: 100%;
    margin: 0 auto;
  }