问题
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:
- In your CSS, all pictures default to
opacity: 0
. - In your HTML, set a class name on one of the pictures that changes that picture's opacity to
1
. - In JavaScript, periodically toggle that class throughout the pictures.
- 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