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
Related
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
I am currently working on a game and I need some help with some html and css.
I have a page called "crime" and there it is 6 possible crimes you can take, on each of them I want to have a progress bar that counts down. I have made it work on the first one, but as I see on the code the keyframes doesnt go to a specific div, but everything that have the "fill" animation.
Since the crimes have different cooldown times I need to have them show another progress then the others.
<div class="bar">
<div class="in"></div>
</div>
.bar {
border: 1px solid #666;
height: 20px;
width: 100%;
}
.in {
animation: fill 20s linear 1;
height: 100%;
background-color: pink;
}
#keyframes fill {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
I think you need to post more code to make us understand precisely what you are doing.
From what you explained so far, I think you just need to create more keyframes and assigned them to the crime you want.
So if you have this for every crime div
<div class="bar">
<div class="in"></div>
</div>
then you could change the name of the inner div for each crime. E.g:
<div class="bar">
<div class="in-1"></div> //bar for crime 1
</div>
<div class="bar">
<div class="in-2"></div> //bar for crime 2
</div>
.in-1 {
animation: fill1 20s linear 1;
height: 100%;
background-color: pink;
}
.in-2 {
animation: fill2 20s linear 1;
height: 100%;
background-color: pink;
}
#keyframes fill1 {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
#keyframes fill2 {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
and so on for all the crimes.
Hope that helped :)
I've been trying to find a solution for a while now but none seem to work.
The issue I am having happens when navigating to any and all the pages on the site- it's very annoying.
While I would expect that site images take time to load, this loading affects my navigation bar and the loading of my site's logo. For the time that it takes each page to load, my site's logo is completely absent- this causes my navigation bar to be shifted all the way up until the logo appears. This usually takes about a split second but it's also completely dependent on the user's internet connection).
How do I prevent this from happening? This causes my entire site to "bounce" when navigating, with all the content being shifted up for a brief moment while the logo is absent.
Give your image tag an absolute height attribute. This will make the browser keep the img tag the height it should be and allow the elements to load in the proper place.
You can also try tweaking a loader to have the page load only when all of the elements in the page have loaded. Something as simple as this:
<!DOCTYPE html>
<html>
<head>
<style>
/* Center the loader */
#loader {
position: absolute;
left: 50%;
top: 50%;
z-index: 1;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Add animation to "page content" */
.animate-bottom {
position: relative;
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 1s;
animation-name: animatebottom;
animation-duration: 1s
}
#-webkit-keyframes animatebottom {
from { bottom:-100px; opacity:0 }
to { bottom:0px; opacity:1 }
}
#keyframes animatebottom {
from{ bottom:-100px; opacity:0 }
to{ bottom:0; opacity:1 }
}
#myDiv {
display: none;
text-align: center;
}
</style>
</head>
<body onload="myFunction()" style="margin:0;">
<div id="loader"></div>
<div style="display:none;" id="myDiv" class="animate-bottom">
<h2>Tada!</h2>
<p>Some text in my newly loaded page..</p>
</div>
<script>
var myVar;
function myFunction() {
myVar = setTimeout(showPage, 3000);
}
function showPage() {
document.getElementById("loader").style.display = "none";
document.getElementById("myDiv").style.display = "block";
}
</script>
</body>
</html>
With some modification, can help the UI experience!
Source: W3 Schools
Hope it helps!
I have an animation where a div slides out the view, however when the animation is completed, the div just returns to its origin position in the view. How do I totally remove the div or hide it after the animation ends using just CSS?
Here is the markup:
<div class="container">
<div class="slide-box" id="slide-box""></div>
</div>
and the css:
.slide-box {
position: relative;
width: 100px;
height: 100px;
background-image: url(../pics/red.png);
background-position: center;
background-size: cover;
background-repeat: no-repeat;
animation: slide 5s linear 1;
}
#keyframes slide {
0% {
left: 0;
}
20% {
left: 20%;
}
40% {
left: 40%;
}
60% {
left: 60%;
}
80% {
left: 80%;
}
100% {
left: 100%;
overflow: hidden;
visibility: hidden;
}
}
I don't want it to fade out over the duration of the animation, i just want it to disappear once it hits 100% in the keyframe. Thanks ahead of time!
Use the animation-fill-mode option. Set it to forwards and the animation ends at it's final state and stay like that.
Altered based upon comments Set opacity fade to just last 1% of animation... simplified keyframes. Added a jquery option to literally remove the div from the DOM. CSS alone won't alter the markup, where jQuery will.
Although you can't animate the display property. If you want the div totally gone, after the opacity fades to zero, you can then add the display property to remove the div. If you don't wait for opacity to end, the div will just vanish without any transition.
/*
This jquery is added to really remove
the div. But it'll essentially be
VISUALLY gone at the end of the
animation. You can not use, or
delete the jquery, and you really
won't see any difference unless
you inspect the DOM after the animation.
This function is bound to animation
and will fire when animation ends.
No need to "guess" at timeout settings.
This REMOVES the div opposed to merely
setting it's style to display: none;
*/
$('.slide-box').bind('animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd', function(e) { $(this).remove(); });
.slide-box {
display: block;
position: relative;
left: 0%;
opacity: 1;
width: 100px;
height: 100px;
background: #a00;
animation: slide 1s 1 linear forwards;
/*
animation-name: slide;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: linear;
animation-fill-mode: forwards;
*/
}
#keyframes slide {
0% {
left: 0%;
opacity: 1;
}
99% {
left: 99%;
opacity: 1;
}
100% {
left: 100%;
opacity: 0;
display: none;
}
}
#-webkit-keyframes slide {
0% {
left: 0%;
opacity: 1;
}
99% {
left: 99%;
opacity: 1;
}
100% {
left: 100%;
opacity: 0;
display: none;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="slide-box" id="slide-box"></div>
</div>
animation: slide 5s linear forwards;
at 100%
opacity: 0;
display: none;
Try this.
Working fiddle: https://jsfiddle.net/jbtfdjyy/1/
UPDATE: JS mani
var slideBox = document.getElementById('slide-box');
setTimeout(function(){
slideBox.style.display = 'none';
}, 5000);
Try this. https://jsfiddle.net/jbtfdjyy/2/
Add something at 99% or so to your keyframes, and set opacity to 1 in that. If you have opacity: 1 at the start, then it will stay that way until 99%. Only at 100% will it change.
It's not technically fired at 100%. If you want that, I'd recommend using some JavaScript here, but this will at least give the illusion you want.
#keyframes slide {
0% {
left: 0;
}
20% {
left: 20%;
}
40% {
left: 40%;
}
60% {
left: 60%;
}
80% {
left: 80%;
}
99% {
opacity: 1;
}
100% {
left: 100%;
overflow: hidden;
opacity: 0;
display: none;
visibility: hidden;
}
}
UPDATE:
As per your request, here is a JavaScript version. Keep in mind, there are endless ways to accomplish such a task. I am using vanilla JS (no jQuery, etc.), and using ES6 syntax.
What we do here is set a timeout, and at the end of that timeout I broadcast an event animation_end. That event listener will handle the end of the animation (in this case, it adds a class which will handle the fading out). This is much more granular than you need it to be, you could simply do the adding of the class within the setTimeout, but I think it is slightly better this way as you can abstract you can do other things with events such as animation start, etc.
Here is the fiddle: https://jsfiddle.net/vmyzyd6p/
HTML:
<div class="container">
<div class="slide-box" id="slide-box""></div>
</div>
CSS:
.slide-box {
position: relative;
width: 100px;
height: 100px;
background-color: blue;
animation: slide 3s linear 1;
-webkit-transition: opacity 2s ease-in-out;
-moz-transition: opacity 2s ease-in-out;
transition: opacity 2s ease-in-out;
}
.animationEnd {
opacity: 0;
}
#keyframes slide {
0% {
left: 0;
}
20% {
left: 20%;
}
40% {
left: 40%;
}
60% {
left: 60%;
}
80% {
left: 80%;
}
100% {
left: 100%;
}
}
JavaScript:
// Create a function that handles the `animation_end` event
const animationEnd = () => {
// Grab the slidebox element
let slideBox = document.getElementById('slide-box');
// Get the class of the slidebox element
let slideClass = slideBox.getAttribute('class');
// Add the animation end class appended to the previous class
slideBox.setAttribute('class', slideClass + ' animationEnd');
};
// Create the animation end event
let animationEndEvent = new Event('animation_end');
// Cross browser implementation of adding the event listener
if (document.addEventListener) {
document.addEventListener('animation_end', animationEnd, false);
} else {
document.attachEvent('animation_end', animationEnd);
}
// Set the timeout with the same duration as the animation.
setTimeout(() => {
// Broadcast the animation end event
document.dispatchEvent(animationEndEvent);
}, 3000);
Example (you can modify and test): http://codepen.io/g-liu/pen/XbrMzr?editors=110
I've modified the code to work in Firefox, but the second animation seems to be skipping frames.
frames: http://www.fabiobiondi.com/blog/wp-content/uploads/2012/08/runningGrant.png
html:
<div id="guy-1" class="guy"></div>
<div id="guy-2" class="guy"></div>
Original sprite
css:
.guy {
height: 294px;
width: 165px;
display: inline-block;
background-image: url(http://www.fabiobiondi.com/blog/wp-content/uploads/2012/08/runningGrant.png);
}
#guy-1 {
animation: run-x 0.4s infinite steps(12);
}
#guy-2 {
animation: run-x 0.4s infinite steps(12), run-y 2.4s infinite steps(6);
}
#keyframes run-x {
from {
background-position: 0 0;
}
to {
background-position: -1980px 0;
}
}
#keyframes run-y {
from {
background-position: 0 0;
}
to {
background-position: 0 -1764px;
}
}
I've solved my problem using LESS (http://lesscss.org/)
It maked the css of animation in a generic way that worked in all browsers (even in mobile).