How to Prevent flicker problem in css animation? - html

I am trying to make a slider using CSS #Keyframes Animation. It works smoothly when I used it for the first time with small size [1100px width and 400px height].
But when I expand the slider and image size for my website, I increase the height and width [1280 * 640]. Then my images are fliker at each interval just for first time, after first time flicker of each image, slider work smoothly.
But I want to prevent it in first time.
CSS:
.slider{
position: relative;
top: 0px;
left: 0px;
background: url(1.jpg);
height: 600px; width: 1263.1px;
margin-bottom: 20px;
animation: slideshow 10s infinite;
}
#keyframes slideshow{
25% { background: url(1.jpg); }
50% { background: url(2.jpg); }
75% { background: url(3.jpg); }
100% { background: url(1.jpg); }
}
HTML:
<div class="slider"></div>

That's because the images haven't loaded, and they only start loading when the animation starts. To prevent this flickering, you can use the onload event in Javascript:
<div class="slider"></div>
<style>
.slider{
background-image: url("1.jpg");
background-repeat: no-repeat;
background-size: cover;
height: 540px;
width: 960px;
}
.slider.loaded{
animation: slideshow 10s infinite;
}
#keyframes slideshow{
0%{
background-image: url("1.jpg");
}
25%{
background-image: url("2.jpg");
}
50%{
background-image: url("3.jpg");
}
75%{
background-image: url("4.jpg");
}
}
</style>
<script>
var images = [
"1.jpg",
"2.jpg",
"3.jpg",
"4.jpg"
];
function loadImg(i){
if(images[i] != undefined){
var img = new Image();
img.src = images[i];
img.onload = function(){ // detect if image has been loaded
i++;
loadImg(i);
}
}
if(images.length == i) // adding class 'loaded' when all images finished with loading
document.getElementsByClassName("slider")[0].classList.add("loaded");
}
loadImg(0);
</script>
NOTE:
I managed to prevent the flickering, but
This only works perfectly in Chrome
Firefox can't animate the images, but the images are still shown
This is absolutely not working in IE / Edge

Related

Why my animation doesnt work on different browsers?

I am currently developing website on Html & CSS & JS.
I cant make my animation work for some reasons. I mean, they work on Google Chrome but not on Mozilla. Here is some code from my CSS file.
<style>
.fullBackground {
background-color: rgba(0,0,0,0.5); /* Tint color */
background-blend-mode: multiply;
background-position: center center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
animation: slideBg 25s linear infinite;
background-image: url("/assets/slideshowImages/1.jpg");
}
#keyframes slideBg {
0% {
background-image: url("/assets/slideshowImages/1.jpg");
}
5% {
background-image: url("/assets/slideshowImages/1.jpg");
}
10% {
background-image: url("/assets/slideshowImages/1.jpg");
}
15% {
background-image: url("/assets/slideshowImages/1.jpg");
}
20% {
background-image: url("/assets/slideshowImages/1.jpg");
}
25% {
background-image: url("/assets/slideshowImages/2.jpg");
}
30% {
background-image: url("/assets/slideshowImages/2.jpg");
}
35% {
background-image: url("/assets/slideshowImages/2.jpg");
}
40% {
background-image: url("/assets/slideshowImages/2.jpg");
}
45% {
background-image: url("/assets/slideshowImages/2.jpg");
}
50% {
background-image: url("/assets/slideshowImages/3.jpg");
}
55% {
background-image: url("/assets/slideshowImages/3.jpg");
}
60% {
background-image: url("/assets/slideshowImages/3.jpg");
}
65% {
background-image: url("/assets/slideshowImages/3.jpg");
}
70% {
background-image: url("/assets/slideshowImages/3.jpg");
}
75% {
background-image: url("/assets/slideshowImages/4.jpg");
}80% {
background-image: url("/assets/slideshowImages/4.jpg");
}85% {
background-image: url("/assets/slideshowImages/4.jpg");
}90% {
background-image: url("/assets/slideshowImages/4.jpg");
}
100% {
background-image: url("/assets/slideshowImages/4.jpg");
}
}
</style>
And here is how I use it in HTML
<div class="fullBackground"></div>
I would be very very glad to you, if you might give me any clue.
Thank you in advance!
As you have said you are using html, css and js for your website, so I would suggest using javascript for consistent results across all browsers.
I don't have a good knowledge of javascript so for transition I am using javascript form w3.schools.com
var myIndex = 0;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("slides");
// The images for transition are selected by the class name of "slides"
//so whichever image has the class name of slides will get picked by this javascript code for the slideshow animation.
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {
myIndex = 1
}
x[myIndex - 1].style.display = "block";
setTimeout(carousel, 4000); // Here 4000 is the time in millisecond fot an image to transition from one to another.
}
.slides {
width: 30rem;
height: 20rem;
}
.fading {
animation: fading 4s infinite /* 4s defines how much time does 1 image takes for fading in and fading out */
}
/* Here the image fades in form opacity 0 to 1 from the 0% time 25% time */
#keyframes fading {
0% {
opacity: 0
}
25% {
opacity: 1
}
75% {
opacity: 1
}
100% {
opacity: 0
}
}
/* The image stays of opacity 1 for the duration of 2s as 25% to 75% of 4s is 2s. */
<img class="slides fading" src="https://picsum.photos/id/10/200/300">
<img class="slides fading" src="https://picsum.photos/id/11/200/300">
<img class="slides fading" src="https://picsum.photos/id/13/200/300">
<img class="slides fading" src="https://picsum.photos/id/16/200/300">
There are comments in the code explaining which element you need to change to get different outcomes.
One thing to keep in mind is if you change the fading animation duration from 4s to any other value you will have to change the timeout value 4000ms in javascript.

Ken Burns Slideshow Modification

I found a slideshow on Codepen that looks like: https://codepen.io/wh1zk1d/pen/WRJjLd
I like this one, but I just wanted the image with the Ken Burns effect, so I simplified the code:
The beauty of this code, is it's very simple :-)
#slides {
background: #000;
height: 450px;
overflow: hidden;
width: 100%;
}
#slides div {
animation: ken-burns 3s ease-out;
animation-fill-mode: both;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
width: 100%;
}
#keyframes ken-burns {
from {
transform: scale(1.2);
} to {
transform: scale(1);
}
}
<div id="slides">
<div style="background-image: url('https://images.unsplash.com/photo-1491609154219-ffd3ffafd992?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80')"></div>
</div>
I have this working on all of my inner pages for a website I am creating, but what I'd like to do on the homepage is use the same concept, with a few modifications, to create a multi-image (4) slideshow...
The way it works right now, is it loads one image and then when the animation completes, it stops. This works great of the inner pages, but on the homepage it'd be nice if this cycled in an infinite continuous loop.
I tried to add another div with a different background image, but the code still works the same way. Loads the image in the first div, then stops.
I'm pretty sure this is a simple tweak, but could someone help me adjust what I'm already using to get multiple images (4) to work, along with a infinite continuous loop of those images?
Thanks,
Josh
So, I found some JS that helped me get this working :-)
The CSS has some minor adjustments...
#slides {
background: #000;
height: 450px;
overflow: hidden;
width: 100%;
}
#slides div.current {
animation: ken-burns 3s forwards;
animation-fill-mode: both;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
width: 100%;
}
#keyframes ken-burns {
0% {
opacity: 0;
transform: scale(1.2);
}
15% {
opacity: 1;
}
85% {
opacity: 1;
}
100% {
opacity: 0;
transform: scale(1);
}
}
The HTML looks a little different as well...
<div id="slides">
<div class="ini" data-imagenum="1" style="background-image: url('https://images.unsplash.com/photo-1497752531616-c3afd9760a11?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2700&q=80'); z-index: -1"></div>
<div class="" data-imagenum="2" style="background-image: url('https://images.unsplash.com/photo-1437622368342-7a3d73a34c8f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1920&q=80'); z-index: -2"></div>
<div class="" data-imagenum="3" style="background-image: url('https://images.unsplash.com/photo-1486365227551-f3f90034a57c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2700&q=80'); z-index: -3"></div>
<div class="" data-imagenum="4" style="background-image: url('https://images.unsplash.com/photo-1425082661705-1834bfd09dca?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2710&q=80'); z-index: -4"></div>
</div>
Then I added some JS...
$(document).ready(function () {
if ($('#slides div').length){
$('.ini').addClass('current');
var numImages = $('#slides div').length;
var i = 1;
$('body').on('webkitAnimationEnd oanimationend msAnimationEnd animationend', '.current', function() {
i ++;
$('.current').removeClass('current');
if ( i <= numImages ) {
$('*[data-imagenum="' + i +'"]').addClass('current');
} else {
i = 1;
$('*[data-imagenum="' + i +'"]').addClass('current');
}
});
}
});
This was as close to my original code as I could get!
Here is the Codepen: https://codepen.io/joshrodgers/pen/ZEQjZNr

Is there a way to make GIF play on hover and pause when mouse is out?

I want to know if there's a way to make a GIF have this exact behavior:
Start paused in the page;
Play only while hovering;
Pause at the exact frame it was when dragging the mouse out of the image.
Is it possible to do this? Preferably without JavaScript, but I can use it if necessary.
There is. Basically you will need to create the gif yourself using individual frames. Essentially, you create X number of frames, then use keyframes to cycle through them as background-image properties of an absolutely positioned div. The "gif" starts with the property animation-play-state:paused and changes to running on hover. It is possible to switch these properties obviously. Consider the following:
Your markup:
<div class="gif"></div>
And your CSS:
.gif {
position: absolute;
margin: auto;
background-image: url(/path/to/starting.frame);
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
animation: play 0.5s infinite steps(1);
animation-play-state: paused;
}
.gif:hover {
animation-play-state:running;
}
#keyframes play {
0% { background-image: url('/path/to/0.frame'); }
15% { background-image: url('/path/to/1.frame'); }
30% { background-image: url('/path/to/2.frame'); }
45% { background-image: url('/path/to/3.frame'); }
60% { background-image: url('/path/to/4.frame'); }
75% { background-image: url('/path/to/5.frame'); }
90% { background-image: url('/path/to/6.frame'); }
100% { background-image: url('/path/to/7.frame'); }
}
Here is an example I was able to find and alter.

Crossfading the background-image of a single element without script

I want to switch background image of the body periodically, cross fading between each image.
A script solution would look like this:
css:
body
{
background-image: url("img/1.jpg");
background-size: cover;
background-position: center 0;
background-attachment: fixed;
transition: background-image 2s ease-in-out;
}
js:
var images = ["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg"];
var current_image = 0;
$(function ()
{
var body = $("body");
setTimeout(next, 10000);
function next()
{
current_image = (current_image + 1) % images.length;
body.css("background-image", "url('img/" + images[current_image] + "')");
setTimeout(next, 10000);
}
});
But is it possible to cross fade the background of a single element (as opposed to change opacities of a number of img elements) using no scripting?
Yeah you could do it with css animations.
something like this.
* { box-sizing: border-box}
.slides {
width: 300px;
height: 300px;
background: tomato;
animation: images 4s linear 0s infinite alternate;
}
#keyframes images {
0% {
background: url('https://fillmurray.com/300/300')
}
50% {
background: url('http://www.placecage.com/c/300/300');
}
100% {
background: url('https://stevensegallery.com/300/300')
}
}
<div class="slides"></div>
I post this as an answer to my own question even if there is a solution that I accepted. What this will add is how to stay for a while on the same image without immediately transitioning to the next.
body {
background-size: cover;
background-position: center 0;
background-attachment: fixed;
animation: images 100s linear 0s infinite;
}
#keyframes images {
0% {
background-image: url("img/1.jpg")
}
19% {
background-image: url("img/1.jpg")
}
20% {
background-image: url("img/2.jpg");
}
39% {
background-image: url("img/2.jpg");
}
40% {
background-image: url("img/3.jpg");
}
59% {
background-image: url("img/3.jpg");
}
60% {
background-image: url("img/4.jpg");
}
79% {
background-image: url("img/4.jpg");
}
80% {
background-image: url("img/5.jpg");
}
99% {
background-image: url("img/5.jpg");
}
100% {
background-image: url("img/1.jpg")
}
}
I tried to group some percentages like
0%, 19%, 100% {
background-image: url("img/1.jpg");
}
but that resulted in "flickering" between images.

How to fill a transparent image with a progress bar ? #CSS #HTML #Jquery?

I'm trying to fill a glass of beer at 30% with html and CSS with the technique of this progress bar csstricks.
But I don't know if it's possible.
I have an image of the glass of beer with transparency content (png in illustrator).
Do you know if it's possible to have the progress bar in background ?
My tests were fruitless.:-(
Or do I have to use another technique ?
Thanks a lot for your help !
Nicolas
There you go :D (this is what you can do with a few alterations to the css-trick example):
Demo: http://jsfiddle.net/djnBD/
<html>
<head>
<meta charset="UTF-8">
<title>Fillable Beer Bottle</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script>
$(function() {
$(".liquid").each(function() {
$(this)
.data("origHeight", $(this).height())
.height(0)
.animate({
height: $(this).data("origHeight")
}, 1200);
});
});
</script>
<style>
.glass {
height: 200px;
position: relative;
background-image: url('http://i40.tinypic.com/11hyr1j.png'); /* Beer Glass */
background-repeat: no-repeat;
}
.liquid {
z-index:-1;
position:absolute;
bottom:0;
width: 200px;
background-image: url('http://i44.tinypic.com/f0vxbt.jpg'); /* Beer Liquid Pattern */
/* Remove the bottom two lines to stop animation */
-webkit-animation: move 150s linear infinite;
-moz-animation: move 150s linear infinite;
}
#-webkit-keyframes move {
0% {
background-position: 0 0;
}
100% {
background-position: 2212px 0px;
}
}
#-moz-keyframes move {
0% {
background-position: 0 0;
}
100% {
background-position: 2212px 0px;
}
}
</style>
</head>
<body>
<div class="glass">
<span class="liquid" style="height: 30%"></span>
</div>
</body>
</html>