在JavaScript中,如何为模态画廊中的每个图像添加动画效果?

问题描述 投票:1回答:2

我有一个图片库,点击后,每个图片都会以模式模式打开。我想向每个动画添加一个动画效果,以便在单击我们的下一个和上一个按钮时显示它们。我将动画样式添加到了我的JS代码中,但是没有按预期工作。它仅在第一次单击时有效,其余部分则无效。

这是我的代码:

var modal = document.getElementById("modalContainer");
var modalImg = document.getElementById("modalImg");
var imgArr = document.querySelectorAll(".img-container .img");
var currentIndex;

imgArr.forEach(function(img, i) {
  img.onclick = function() {
    var backgroundImage = img.style.backgroundImage
      .slice(4, -1)
      .replace(/"/g, "");
    modal.style.display = "block";
    modalImg.src = backgroundImage;
    currentIndex = i;
    modalImg.style.animation = "fadeInLeft .4s both";
  };
});

var prev = document.querySelector("#prev");
var next = document.querySelector("#next");

next.addEventListener("click", nextImage);
modalImg.addEventListener("click", nextImage);

function nextImage() {
  if (currentIndex < imgArr.length - 1) {
    currentIndex++;
    modalImg.src = imgArr[currentIndex].style.backgroundImage
      .slice(4, -1)
      .replace(/"/g, "");
  }
  modalImg.style.animation = "fadeInLeft .4s both";
}

prev.addEventListener("click", previousImage);

function previousImage() {
  if (currentIndex > 0) {
    currentIndex--;
    modalImg.src = imgArr[currentIndex].style.backgroundImage
      .slice(4, -1)
      .replace(/"/g, "");
  }
  modalImg.style.animation = "fadeInLeft .4s both";
}

var closeModal = document.getElementsByClassName("modal-close")[0];
closeModal.addEventListener("click", close);

function close() {
  modal.style.display = "none";
}
.gallery-container {
  width: 500px;
  height: 200px;
  display: flex;
  flex-direction: row;
}

.img {
  display: block;
  max-width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  cursor: pointer;
}

.img-container {
  display: block;
  width: 100%;
  height: 100%;
  position: relative;
}

.modal-container {
  display: none;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background-color: rgba(244, 244, 244, 0.9);
  outline: none !important;
  position: fixed;
  z-index: 10;
}

.modal-content {
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  text-align: center;
  padding: 0 8px;
  position: absolute;
  z-index: 1;
}

.modal-content-inner {
  width: 100%;
  height: 100%;
}

.modal-figure {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  flex-direction: column;
  animation: fadeInLeft 0.4s both;
}

figure {
  max-width: 90%;
  height: 100%;
  margin: auto;
  display: flex;
  padding: 0;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  padding: 1rem 0;
  position: relative;
}

.modal-img {
  max-height: 90%;
  max-width: 100%;
  border-radius: 0.2rem;
  box-shadow: 0 4px 8px 0 rgba(51, 51, 51, 0.2), 0 6px 20px 0 rgba(51, 51, 51, 0.19);
}

.modal-close,
.modal-arrow,
.modal-img {
  z-index: 999;
}

.modal-close,
.modal-arrow {
  cursor: pointer;
  background: transparent;
  border: 0;
  -webkit-appearance: none;
  display: block;
  outline: none;
  padding: 0.8rem;
  -webkit-box-shadow: none;
  box-shadow: none;
}

.modal-close:hover,
.modal-arrow:hover {
  color: #000;
}

.modal-arrow {
  cursor: pointer;
  position: absolute;
  top: 50%;
  -moz-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
  width: auto;
  color: #7c7c7c;
  font-weight: normal;
  font-size: 1.8rem;
  transition: 0.6s ease;
  border-radius: 0 .3rem .3rem 0;
  user-select: none;
  -webkit-user-select: none;
}

.modal-close {
  color: #7c7c7c;
  font-size: 2rem;
  font-weight: normal;
  padding-right: 0;
  position: relative;
  align-self: flex-end !important;
}

#next {
  right: 0;
}

#prev {
  left: 0;
}

@keyframes fadeInLeft {
  0% {
    opacity: 0;
    -webkit-transform: translateX(-20px);
    -ms-transform: translateX(-20px);
    transform: translateX(-20px);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateX(0);
    -ms-transform: translateX(0);
    transform: translateX(0);
  }
}
<div class="gallery-container">
  <div class="img-container">
    <div class="img" style="background-image: url(https://images.unsplash.com/photo-1501159771943-cc9027db4d8b?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80)">
    </div>
  </div>
  <div class="img-container">
    <div class="img" style="background-image: url(https://images.unsplash.com/photo-1509042239860-f550ce710b93?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80)">
    </div>
  </div>
  <div class="img-container">
    <div class="img" style="background-image: url(https://images.unsplash.com/photo-1583936410736-a4af4f3013d6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)">
    </div>
  </div>
</div>
<div id="modalContainer" class="modal-container">
  <div class="modal-content">
    <div class="modal-content-inner">
      <div class="modal-figure">
        <figure>
          <button id="close" class="modal-close">&times;</button>
          <img id="modalImg" class="modal-img">
          <figcaption>
            <div id="caption" class="modal-caption"></div>
        </figure>
        <div class="modal-container-close"></div>
      </div>
    </div>
    <button id="prev" class="modal-arrow">&#10094;</button>
    <button id="next" class="modal-arrow">&#10095;</button>
  </div>
</div>
javascript css animation image-gallery
2个回答
3
投票

您可以通过已定义动画的animationName属性动画或通过类名进行动画效果来达到目的。

请参见example

无论如何,完成后都应删除动画

function onAnimationEnd(){
/*
  // Options 1: Manipulate class name
  this.classList.remove('fade')
*/
  imgContainer.style.animationName = 'none';
}
imgContainer.addEventListener('animationend', onAnimationEnd);

0
投票

您可以简化以避免重复:

const prev = document.querySelector("#prev");
const next = document.querySelector("#next")
const btn = document.querySelector(".modal-arrow")
btn.addEventListener("click", showImage);

function animate(i) {
  caption.innerHTML = captionArr[i];
  modalImg.style.animationName = 'fadeInLeft';
}

function showImage() {
  if (next && currentIndex < imgArr.length - 1 ) {
    currentIndex++;
  } else if (prev && currentIndex > 0) {
    currentIndex--;
  } else {
    currentIndex = 0
  }
  animate(currentIndex)
}

这只是一个示例,请对其进行更改以与您的代码一起使用。

代替currentIndex = 0,您可以在此处执行return语句或回调函数,该函数确定当用户在最后一张图像上单击“下一步”或在第一张图像上单击“上一页”时会发生什么。

© www.soinside.com 2019 - 2024. All rights reserved.