How to use @keyframes for cross-fade gallery of images in css?

时间秒杀一切 提交于 2019-12-11 07:48:07

问题


I have a fiddle (Fiddle A) in which cross-fade gallery of images happen for 2 images (2 tiles). Here is the snippets of html/css which I have used.

<div class="featured-block" style="display:flex; justify-content: center;">
  <a href="https://www.google.com/" class="featured-block__item cf">
    <div class="featured-block__item-inner">
      <figure class="featured-block__image img-fit" itemprop="image" itemscope="" itemtype="http://schema.org/ImageObject">
        <img class="default-opacity" src="https://i.imgur.com/EUqZ1Er.png" data-fallback-img="https://i.imgur.com/EUqZ1Er.png" alt="Outburst">
      </figure>
    </div>
  </a>
</div>

Here are the @keyframes which I have used 2 images (2 tiles) for the above html:

@keyframes cf4FadeInOut {
    0% {
        opacity: 0;
    }
    20% {
        opacity: 1;
        z-index: 999;
    }
    33% {
        opacity: 1;
    }
    53% {
        opacity: 0;
        z-index: 1;
    }
    100% {
        opacity: 0;
    }
}

The above css-animation in Fiddle A is working perfectly fine(which is exactly what I want) when there are 2 tiles (2 images).

Problem Statement:

The above fiddle (Fiddle A) is working perfectly fine for 2 images. I want the same css-animation/cross-fade gallery of images happens when there 3 and 4 images.

Here is the fiddle for 4 images(4 tiles) https://jsfiddle.net/zwjt8qko/1/embedded/result (Fiddle B)

Here is the fiddle for 3 images(3 tiles) https://jsfiddle.net/f6gr7kL1/embedded/result (Fiddle C)

I am wondering what changes I should make in the keyframes in the Fiddle B (4 images) and Fiddle C (3 images) above so that the same css-animation/cross-fade happens which is happening in Fiddle A right now.

I am open to a JavaScript solution as well.


回答1:


JavaScript method

Basic approach:

  1. In your CSS, all pictures default to opacity: 0.
  2. In your HTML, set a class name on one of the pictures that changes that picture's opacity to 1.
  3. In JavaScript, periodically toggle that class throughout the pictures.
  4. Don't even bother with keyframes and just do our delaying in JavaScript directly. This lets you more easily modify how long you want different parts of the pulsing animation to last instead of having to calculate the percentage of the total animation-duration like you'd have to with keyframes.

const pics = document.querySelectorAll('.pic');
const lastPic = pics.length - 1;
const transitionDuration = 800; // matches CSS
const transitionDelay = 3000; // up to you
const totalDelay = transitionDuration + transitionDelay;
const intervalDelay = (transitionDuration * 2) + transitionDelay; // time to fade out + time to fade in + time to stay active

function toggleClass() {
  const activePic = document.querySelector('.pic.active');
  const activeIndex = Array.prototype.indexOf.call(pics, activePic);
  const nextIndex = activeIndex === lastPic ? 0 : activeIndex + 1;
  const nextPic = pics[nextIndex];

  setTimeout(() => activePic.classList.remove('active'), transitionDelay);
  setTimeout(() => nextPic.classList.add('active'), totalDelay);
}

setInterval(toggleClass, intervalDelay);
.wrapper {
  width: 400px;
  height: 300px;
  position: relative;
}
.pic {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  opacity: 0;
  transition: opacity 800ms ease; /* immediately start fading out when active class is lost */
}
.pic.active {
  opacity: 1;
}
<div class="wrapper">
  <img class="pic active" src="https://via.placeholder.com/400x300?text=picture%201" alt="">
  <img class="pic" src="https://via.placeholder.com/400x300?text=picture%202" alt="">
  <img class="pic" src="https://via.placeholder.com/400x300?text=picture%203" alt="">
  <img class="pic" src="https://via.placeholder.com/400x300?text=picture%204" alt="">
</div>

Keyframes method

I won't go into full detail here, but it would probably look something like this:

@keyframes pulse1 {
  0% {
    opacity: 1;
  }
  20% {
    opacity: 0;
  }
}

@keyframes pulse2 {
  0% {
    opacity: 0;
  }
  25% {
    opacity: 1;
  }
  45% {
    opacity: 0;
  }
}

@keyframes pulse3 {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  70% {
    opacity: 0;
  }
}

@keyframes pulse4 {
  0% {
    opacity: 0;
  }
  75% {
    opacity: 1;
  }
}

Note that we don't even toggle the z-index because there's no point: only one of them is ever visible at a time. Just position them all on top of each other from the start, and their z-index won't matter.

(I don't think the z-index portion of the animation you have in your question is even doing anything because z-index isn't animatable.)



来源:https://stackoverflow.com/questions/57481429/how-to-use-keyframes-for-cross-fade-gallery-of-images-in-css

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!