CSS animation only display on first slide image - javascript

I want to make few images displaying as slides with fadeIn effect in css. Everything works fine, images are displayed in 3s period with setInterval javascript method, but only first image displays with fadeIn animation.
.slide {
position: absolute;
height: 100vh;
width: 66vw;
animation: fadeIn 1s;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<img class="slide" src="https://static.vecteezy.com/packs/media/components/global/search-explore-nav/img/vectors/term-bg-1-666de2d941529c25aa511dc18d727160.jpg">
There is only one jpg added to HTML and javascript code is written to replace file path from
<img class="slide" src="1.JPG">
to "2.jpg", "3.jpg" etc
Only first image has animation, everything displayed later is without animation.
When I check console, all next images still have .slide class and all its properties position/width/height/animation, but they display without animation.
Any ideas ?

Basically, you need to trigger the css animation every time you change the src. You can do it by removing the element class, triggering a DOM reflow, and adding the class again. But you should be careful because triggering reflow can be an expensive operation. Read more about it here.
const images = [
"https://via.placeholder.com/300?text=image1",
"https://via.placeholder.com/300?text=image2",
"https://via.placeholder.com/300?text=image3",
];
const img = document.querySelector(".slide");
let imageIndex = 0;
const imageInterval = setInterval(() => {
imageIndex++;
if (imageIndex >= images.length) {
clearInterval(imageInterval);
} else {
img.src = images[imageIndex];
img.classList.remove("slide");
void img.offsetWidth; // trigger a DOM reflow
img.classList.add("slide");
}
}, 3000);
.slide {
position: absolute;
height: 100vh;
width: 66vw;
animation: fadeIn 1s;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<img class="slide" src="https://via.placeholder.com/300?text=image1">

Hard to tell what exactly you want but with pure CSS perhaps something like this
.slide {
position: absolute;
opacity: 0;
height: 100vh;
width: 66vw;
animation: fadeIn 1s forwards;
}
.two {
animation-delay: 3s;
}
.three {
animation-delay: 6s;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<img class="slide" src="https://static.vecteezy.com/packs/media/components/global/search-explore-nav/img/vectors/term-bg-1-666de2d941529c25aa511dc18d727160.jpg">
<img class="slide two" src="https://compote.slate.com/images/f063a07e-e5ab-4e04-8093-281d0a28ebe8.jpeg">
<img class="slide three" src="https://i.ytimg.com/vi/nWLUdoK5fSs/maxresdefault.jpg">

Related

How do I get Javascript to run animation instead of CSS

I am doing a splash screen for my website. I have managed to get it working as JS wasn't working.
"use strict";
$(function(){
$('.fadein img:gt(0)').hide();
setInterval(function(){
$('.fadein :first-child').fadeOut()
.next('img').fadeIn()
.end().appendTo('.fadein');},
6000);
});
const splash = document.querySelector('.splash');
document.addEventListener('DOMContentLoaded', (e)=> {
setTimeout(function()=> {
splash.classList.add('display-none');
}, 10000);
})
The bottom code breaks the top code (which works and runs the slideshow).
.splash {
position: fixed;
top: 0;
left: 0;
width: auto;
height: auto;
z-index: 200;
}
.splash.display-none {
position: fixed;
opacity: 0;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: -10;
transition: all 6s;
}
#keyframes fadeIn {
to{
opacity: 0;
visibility: hidden;
}
}
#-webkit-keyframes fadeIn {
to{
opacity: 0;
visibility: hidden;
}
}
.splash {
opacity: 1;
animation: fadeIn 2s ease-in forwards;
-webkit-animation: fadeIn 2s ease-in forwards;
animation-delay: 0.75s;
}
.fade-in {
height: 100vh;
width: 100%;
}
This is my CSS, and the animation works. My only problem with it is that if I went back to homepage, the animation would happen again. This is why I want to use Javascript so it only happens on a new instance of loading the website.
Use localStorage to see if splash screen has been shown already. Set them to display:none immediately so they are completely hidden. I'm not sure what you actually want to happen with the splash, so I'm just hiding them completely. I think it would be more pleasant to just have a very short opacity transition instead.
You can use localStorage.removeItem to clear the splashed flag.
You may want to use a unique ID for the localStorage name for this specific splash, and not just "splashed".
document.addEventListener('DOMContentLoaded', (e)=> {
const splashed = localStorage.getItem('splashed')
const splash = document.querySelector('.splash');
const splasher = () => {
splash.classList.add('display-none');
localStorage.setItem('splashed',1)
};
splashed ? splash.forEach(x=>x.style.display='none') : setTimeout(splasher, 10000);
})

Activate animation when in viewport

I am trying to use animate to make images transition from zero opacity to full opacity. The keyframes animation code i have used works but i want to delay the start until the image is in view.
I have tried several JS codes which have not worked.
HTML
<div class="item2">
<img src="images/winston-chen-qg8TGmBNdeY-unsplash.jpg" width="950" height="700" alt="wintson cheng unsplash" class="img">
</div>
CSS
#keyframes animate {
from {opacity: 0;}
to {opacity: 1;}
}
.img {
width: 100vw;
height: auto;
animation-name: animate;
animation-duration: 10s;
animation-timing-function: ease-in;
}
You could do it easily with jQuery.
CSS:
img { opacity: 0; } /* this sets the opacity before it comes in so there isn't a jump */
.img {
width: 100vw;
height: auto;
}
.fadein {
animation: animate 10s forwards;
}
jQuery:
https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
Then in scripts file:
$(function() {
$(window).scroll(function() {
var $img = $(".img");
$img.each(function() {
var $y = $(document).scrollTop(),
$wh = $(window).height(),
$t = $(this).offset().top - $wh;
if ($y > $t) {
$(this).addClass("fadein");
}
});
});
});
Every time the .img tag comes into view it adds the fadein class and fades in.

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

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.
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.)

Random animation on Simple Image Slideshow

I want to apply a random animation on my slideshow image. First, I tried adding an animation such as scale but it didn't work as I wanted it to.
Things I want to fix:
Smoothness on fadein
Random animation (can be anything at this point, I just want to see how it's done)
Fiddle: http://jsfiddle.net/jzhang172/e7cLtsg9/1/
$(function() {
$('img').hide();
function anim() {
$("#wrap img").first().appendTo('#wrap').fadeOut(3500).addClass('transition').addClass('scaleme');
$("#wrap img").first().fadeIn(3500).removeClass('scaleme');
setTimeout(anim, 3700);
}
anim();
});
body,
html {
margin: 0;
padding: 0;
background: black;
}
#wrap img {
position: absolute;
top: 0;
display: none;
width: 100%;
height: 100%;
}
.transition {
transition: 10s;
}
.scaleme {
transition: 10s;
transform: scale(1.3);
}
.box {
height: 300px;
width: 500px;
position: relative;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
<div id="wrap">
<img src="http://elegantthemes.com/preview/InStyle/wp-content/uploads/2008/11/s-1.jpg" />
<img src="http://elegantthemes.com/preview/InStyle/wp-content/uploads/2008/11/s-5.jpg" />
<img src="http://elegantthemes.com/preview/InStyle/wp-content/uploads/2008/11/s-3.jpg" />
</div>
</div>
Here is a sample using CSS animations and jQuery (for achieving the randomness of animations). If you don't wish to use CSS animations and want to stick to transitions + jQuery effects (like fadeIn), you can still adapt this code to support it because the base idea will still remain the same. I am not too comfortable with jQuery effects and have hence stuck to using CSS animations.
Below is an overview of how it is being done (refer inline comments for more details):
Inside a wrapper there are a group of images that are part of the slide-show (like in your demo).
Using CSS #keyframes, a list of animations (one of which would be used randomly) is created in addition to the default fade-in-out animation. This list is also maintained in an array variable (in JS for picking up a random one from the list).
On load, the default fade-in-out animation and one random animation is added to the 1st element.
An animationend event handler is added to all of the images. This event handler will be triggered when the animation on an element ends. When this is triggered, animation on the current element is removed and the default fade-in-out + a random animation is added to the next element.
The animations are added using inline styles because if we add multiple CSS classes each with one different animation, then the animation in the latest class will override the others (that is, they will not happen together).
A loop effect is achieved by checking if the current element has any other img sibling elements. If there are none, the animation is added back to the 1st element.
$(window).load(function() {
$img = $('img'); // the images
var anim = ['zoom', 'shrink', 'move-down-up', 'move-right-left']; // the list of random animations
var rand = Math.floor(Math.random() * 4) + 1; // random number
$img.each(function() { // attach event handler for each image
$(this).on('animationend', function(e) { // when animation on one image has ended
if (e.originalEvent.animationName == 'fade-in-out') { // check the animation's name
rand = Math.floor(Math.random() * 4) + 1; // get a random number
$(this).css('animation-name', 'none'); // remove animation on current element
if ($(this).next('img').length > 0) // if there is a next sibling
$(this).next('img').css('animation-name', 'fade-in-out, ' + anim[rand - 1]); // add animation on next sibling
else
$img.eq(0).css('animation-name', 'fade-in-out, ' + anim[rand - 1]); // else add animation on first image (loop)
}
});
});
$img.eq(0).css('animation-name', 'fade-in-out, ' + anim[rand - 1]); //add animation to 1st element on load
})
#wrapper {
height: 250px;
width: 300px;
position: relative;
}
img {
position: absolute;
z-index: 1;
bottom: 20px;
left: 10px;
opacity: 0;
transform-origin: left top; /* to be on the safe side */
animation-duration: 3s; /* increase only if you want duration to be longer */
animation-fill-mode: backwards; /* fill mode - better to not change */
animation-iteration-count: 1; /* no. of iterations - don't change */
animation-timing-function: ease; /* better to leave as-is but can be changed */
}
#keyframes fade-in-out {
0%, 100% {
opacity: 0;
}
33.33%, 66.66% { /* duration is 3s, so fade-in at 1s, stay till 2s, fade-out from 2s */
opacity: 1;
}
}
#keyframes zoom {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.5);
}
}
#keyframes shrink {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(.5);
}
}
#keyframes move-down-up {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(50px);
}
}
#keyframes move-right-left {
0%, 100% {
transform: translateX(0px);
}
50% {
transform: translateX(50px);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<img src="https://placehold.it/200/000000/ffffff" />
<img src="https://placehold.it/200/ff0000/ffffff" />
<img src="https://placehold.it/200/00ff00/ffffff" />
<img src="https://placehold.it/200/0000ff/ffffff" />
</div>

Immediately reverse CSS3 animation

When I add the .shown class to my #overlay I would like the opacity to fade in for 2secs, then immediately reverse and fade out for 2 seconds, creating a sort of "flashing" effect.
I tried just removing the class but that doesn't show any animation at all. This is my sample markup/CSS:
HTML:
<div id="outer">
This is some text
<div id="overlay"></div>
</div>
CSS:
#overlay {
...
opacity: 0;
transition: opacity 2s ease-in-out;
}
#overlay.shown {
opacity: 0.3;
}
Attemped JS:
// Wait 2 seconds from page load...
setTimeout(function() {
// Add shown class to trigger animation
document.getElementById("overlay").classList.add("shown");
// Want to remove the class and hoped this would reverse the animation...
// it doesn't
document.getElementById("overlay").classList.remove("shown");
}, 2000);
jsFiddle
use css animation with keyframes
#keyframes myFlash
{
0% {opacity:0;}
50% {opacity:0.3;}
100% {opacity:0;}
}
#-webkit-keyframes myFlash /* Safari and Chrome */
{
0% {opacity:0;}
50% {opacity:0.3;}
100% {opacity:0;}
}
#overlay {
...
opacity: 0;
}
#overlay.shown {
animation:myFlash 2s;
-webkit-animation:myFlash 2s; /* Safari and Chrome */
}
It looks like you could use a second timeout after the first animation completes..
// Wait 2 seconds from page load...
setTimeout(function() {
// Animate Forward
document.getElementById("overlay").classList.add("shown");
setTimeout(function(){
// Animate Back
document.getElementById("overlay").classList.remove("shown");
},2000);
}, 2000);
There are lots of changes i have done to achieve your out put please check following code
Your css
#outer {
width: 100px;
height: 100px;
position: relative;
}
#overlay {
top: 0;
left: 0;
position: absolute;
width: 100%;
height: 100%;
background: #336699;
opacity: 0;
transition: opacity 2s ease-in-out;
}
#overlay.shown {
display: block;
opacity: 0.5;
}
Your js
setTimeout(function() {
$("#overlay").addClass("shown");
var def = $('#overlay').promise();
def.done(
function () {
$('body').stop().delay(5000).queue(function(){
$("#overlay").removeClass("shown");
});
});
}, 2000);
There was no delay between first and second so how it will show animation which you have done
Please check working demo.....Demo

Categories

Resources