Apply different animations to multiple backgrounds images in a single class - html

I have a single class named slider .I need to have different types of animation for different images.Please help me to implement that .Now all my images are having same mode of animation.I just want to keep a single class slider.
Here is my code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
margin:0p;
padding:0p;
background: green;
perspective: 800px;
height: 100vh;
width: 100wh;
}
.slider{
/* background-image: url(https://www.mozilla.org/media/img/logos/firefox/logo-quantum.9c5e96634f92.png);
background-size: 800px 800px;
width: 800px;
height: 800px;
border: 2px solid;
color: pink;
*/
width:100vw;
height:100vh;
background: url(b1.jpg);
background-size: 100wh 100vh;
/* animation: slide 2s infinite;*/
animation: slide
2s infinite;
margin: 100px auto;
}
#keyframes slide{
from{
/* transform:rotateY(0deg);*/
/* transform: rotate3d(1, 1, 1, 0deg);*/
transform: rotate3d(0, 1, 0, 0deg);
background-color: pink;
}
to{
/* transform:rotateY(180deg);
transform: rotate3d(1, 1, 1, 360deg);*/
transform: rotate3d(0, 1, 0, 360deg);
background-color: pink;
}
25%{
background-image: url(b2.jpg);
background-size: 100wh 100vh;
}
50%{
background-image: url(b3.jpg);
background-size: 100wh 100vh;
}
75%{
background-image: url(b4.jpg);
background-size: 100wh 100vh;
}
100%{
background-image: url(b5.jpg);
background-size: 100wh 100vh;
}
}
</style>
</head>
<body>
<div class="slider"></div>
</body>
</html>
Here is the fiddle
My fiddle
Also one more doubt in each image there seems to be a repetition of image as if the same image gets reduced and a part of the image is getting added there .I just want to have a single image with 100% view not repetition.
Any help would be highly appreciated

This is called a slider and looking at the keyframes definition it seems as though you want to rotate a set of images in order using one animation, not different animations for each image. Tfhis is doable as long as you don't want totally different animations for each 'slide'.
A couple of points:
Your 'doubt' is justified. The image is being repeated as that is the default for background in CSS, set it to 'no-repeat' so you don't get the little extra bits.
The images may (or may not, depends on your use case, but in general) have differing aspect ratios and they may be different or not from the aspect ratio of the viewport (which the containing element uses to set its dimensions). Use either background-size: contain to ensure you see the whole image for every one, or cover if you want to have the entire viewport covered, though in that case either the top and bottom or the side may get cropped to fit
You probably want the background-position to be centered both horizontally and vertically rather than left and top which would be the default in this case.
Here's an altered snippet. Note that the sizes transform over a short time which you may or may not want. You can alter the keyframes to stop that (let me know if you need help with that). Also the very last image has no time to show itself so you probably want to look at the % settings to make sure it gets a look in.
body {
margin: 0p;
padding: 0p;
background: green;
perspective: 800px;
height: 100vh;
width: 100wh;
}
.slider {
/* background-image: url(https://www.mozilla.org/media/img/logos/firefox/logo-quantum.9c5e96634f92.png);
background-size: 800px 800px;
width: 800px;
height: 800px;
border: 2px solid;
color: pink;
*/
width: 100vw;
height: 100vh;
background: url(https://picsum.photos/id/1023/300/300);
background-repeat: no-repeat no-repeat;
/* ADDED */
background-position: center center;
/* ADDED */
background-size: cover;
/* ADDED - TRY BOTH TO DECIDE WHICH YOU WANT IF YOU HAVE IMAGES OF DIFFERENT ASPECT RATIOS */
background-size: contain;
/* ADDED */
background-size: 100wh 100vh;
/* animation: slide 2s infinite;*/
animation: slide 2s infinite;
margin: 100px auto;
}
#keyframes slide {
from {
/* transform:rotateY(0deg);*/
/* transform: rotate3d(1, 1, 1, 0deg);*/
transform: rotate3d(0, 1, 0, 0deg);
background-color: pink;
}
to {
/* transform:rotateY(180deg);
transform: rotate3d(1, 1, 1, 360deg);*/
transform: rotate3d(0, 1, 0, 360deg);
background-color: pink;
}
25% {
background-image: url(https://picsum.photos/id/1015/1024/768);
background-size: 100wh 100vh;
}
50% {
background-image: url(https://picsum.photos/id/1016/768/1024);
background-size: 100wh 100vh;
}
75% {
background-image: url(https://picsum.photos/id/1018/200/300);
background-size: 100wh 100vh;
}
100% {
background-image: url(https://picsum.photos/id/1020/300/300);
background-size: 100wh 100vh;
}
}
<div class="slider"></div>
UPDATE
In the above snippet each image gets the same animation. The requirement is for each to have its own (rotation, zoom et al). This can be achieved while still maintaining the single slider class requirement by having each part of the keyframes define the animation for that particular slide.
In this snippet there are 4 slides, each takes one quarter of the overall alloted time for one iteration of the animation. In each part the particular animation required is defined. This snippet assumes that you want to do the animation bit for half the time an image has the show it without moving for the remaining half. These timings can be altered by altering the %s in the keyframes.
The first image rotates, the second image zooms, the third image comes in from 0 opacity and the fourth image just shows without moving.
Obviously more images can be added and different types of movement, scaling, opacity defined by altering %s and inserting more background images.
Note: opacity will refer to the whole element, so the backgroud pink color also faded which looked odd so I removed it. If it is important to have a background you will have to think about an extra element and animating that, or decide not to use opacity as one of the things that change, or have green to pink change anyway.
body {
margin: 0p;
padding: 0p;
background: green;
perspective: 800px;
height: 100vh;
width: 100wh;
}
.slider {
width: 100vw;
height: 100vh;
background-repeat: no-repeat no-repeat;
/* ADDED */
background-position: center center;
/* ADDED */
background-size: cover;
/* ADDED - TRY BOTH TO DECIDE WHICH YOU WANT IF YOU HAVE IMAGES OF DIFFERENT ASPECT RATIOS */
background-size: contain;
/* ADDED */
animation: slide 16s infinite;
margin: 100px auto;
}
#keyframes slide {
0% {
transform: rotate3d(0, 1, 0, 0deg);
opacity: 1;
background-image: url(https://picsum.photos/id/1023/300/300);
}
12.5%,
24.99% {
/* to make the slide not move between those times */
transform: rotate3d(0, 1, 0, 360deg);
opacity: 1;
background-image: url(https://picsum.photos/id/1023/300/300);
}
25% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1015/1024/768);
}
37.5%,
49.99% {
/* so it scales up for the first half of its time, then stays there showing */
transform: rotate3d(0, 0, 0, 0deg) scale(1.5);
opacity: 1;
background-image: url(https://picsum.photos/id/1015/1024/768);
}
50% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 0;
background-image: url(https://picsum.photos/id/1016/768/1024);
}
74.99% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1016/768/1024);
}
75% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1018/200/300);
}
100% {
transform: rotate3d(0, 0, 0, 0deg) scale(1);
opacity: 1;
background-image: url(https://picsum.photos/id/1018/200/300);
}
}
<div class="slider"></div>
The overall aimation has time of 16s to give each image 2 seconds to move and 2 seconds staying still.
You will find that you need to play around with opacity to stop very sudden changes if this is a problem.
The snippet repeats both the transform and the opacity setting each time which is not always necessary, but I find it serves as a reminder that transform needs all the settings in it, it's not 'cumulative'.

Related

CSS keyframes animation glitching in first cycle but running smoothly in following cycles [duplicate]

This question already has an answer here:
How can I apply css transitions to a background image change?
(1 answer)
Closed 3 months ago.
I created a CSS keyframes animation with 5 frames where the background image would fade and change to the next image. The animation works like its supposed to in all cycles except during the first cycle where it glitches before each transition. How to fix this?
HTML:
<div class="container"></div>
CSS:
#keyframes animation1 {
0%, 15%{background-image: url("https://i.imgur.com/IzY1cRC.jpeg");}
20%, 35%{background-image: url("https://i.imgur.com/Bq4PJjC.jpeg");}
40%, 55%{background-image: url("https://i.imgur.com/43idGF1.jpg");}
60%, 75%{background-image: url("https://i.imgur.com/OMa9YYH.jpg");}
80%, 95%{background-image: url("https://i.imgur.com/CTLFd8t.jpg");}
100%{background-image: url("https://i.imgur.com/IzY1cRC.jpeg");}
}
.container{
height: 300px;
width: 550px;
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
animation-name: animation1;
animation-duration: 25s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
Extremely grateful for any help this has been hindering a couple of projects for a good time.
The first time the animation plays, images will not be loaded yet, the browser will fetch only when they're actually needed.
While the image is loading, the default background will be displayed (in this case, transparent, which will ultimately show the white background of the body)
You can 'pre-load' the images. So the browser already had the image data in cache when it's needed for the animation. There's different techniques for pre-loading. A straightforward way is to add an invisible element that requires all the images used in the animation.
In the example below, we add an 'invisible' :after element that loads all images.
.container::after {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
z-index: -1;
content: url(https://i.imgur.com/IzY1cRC.jpeg) url(https://i.imgur.com/Bq4PJjC.jpeg) url(https://i.imgur.com/43idGF1.jpg) url(https://i.imgur.com/OMa9YYH.jpg) url(https://i.imgur.com/CTLFd8t.jpg) url(https://i.imgur.com/IzY1cRC.jpeg);
}
#keyframes animation1 {
0%,
15% {
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
}
20%,
35% {
background-image: url("https://i.imgur.com/Bq4PJjC.jpeg");
}
40%,
55% {
background-image: url("https://i.imgur.com/43idGF1.jpg");
}
60%,
75% {
background-image: url("https://i.imgur.com/OMa9YYH.jpg");
}
80%,
95% {
background-image: url("https://i.imgur.com/CTLFd8t.jpg");
}
100% {
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
}
}
.container {
height: 300px;
width: 550px;
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
animation-name: animation1;
animation-duration: 25s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
<div class="container"></div>

How to set transition for 2 backgrounds in an element?

in this code:
#p1 {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-color: #05080d;
background-position: left top, left bottom;
background-size: 100% 35%, 100% 65%;
}
I want when the page shows up, first show backimgs/first/1.jpg then after 1 sec show backimgs/first/2.jpg. how can I do it?
You can't animate background-images. You can change it, but there won't be any smooth transition:
#p1 {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-color: #05080d;
background-position: left top, left bottom;
background-size: 100% 35%, 100% 65%;
animation: change-bg;
animation-duration: 1s;
}
#keyframes change-bg {
0% {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-size: 100% 35%, 100% 65%;
}
100% {
background-image: url(backimgs/first/2.jpg), url(backimgs/first/1.jpg);
background-size: 100% 65%, 100% 35%;
}
}
If you want a smooth transition - you can use ::before and ::after with a background and animate the opacity of them. Let me know with a comment if you need more info on this aproach, I'll edit the post and show, how it's done.
You mention 'transition' in the title so you will need to control the two parts of the background separately.
To enable this, this snippet removes the backgrounds from the element itself, instead putting them onto two pseudo elements. The before pseudo element having the first image as background and the after pseudo element having the second one.
Separating the components in this way means we can animate the opacities, the first pseudo element going from opacity 0 to opacity 1 in the first second.
Note however that a little hack has been added to ths snippet. As the animation on the before pseudo element is to happen on load then there needs to be some method of waiting for the background image to load before the animation starts else there is a danger it will be part way through, or even finished, before the image is actually available.
I do not know the wider context of how you are testing for load being complete so have just put a delay in here for demo purposes. You'll need to decide what to do to avoid this inital load situation.
* {
margin: 0;
padding: 0;
}
#p1 {
/* added for this demo */
display: inline-block;
width: 100vw;
height: 100vh;
position: relative;
}
#p1::before,
#p1::after {
content: '';
position: absolute;
z-index: -1;
width: 100%;
left: 0;
display: inline-block;
background-color: #05080d;
background-size: cover;
background-repeat: no-repeat no-repeat;
background-position: center center;
animation: fadein 1s linear;
animation-fill-mode: forwards;
opacity: 0;
}
#p1::before {
top: 0;
height: 35%;
background-image: url(https://picsum.photos/id/1018/1024/768);
animation-delay: 1s;
/* a hack to ensure it is loaded before start the animation */
}
#p1::after {
bottom: 0;
height: 65%;
background-image: url(https://picsum.photos/id/1015/1024/768);
animation-delay: 2s;
}
#keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="p1"></div>

CSS animation not smooth enough

The animation is moving linearly from left to right but starts abruptly once the animation time is over. Tried with reducing to 1s and increasing the time to 15s. And even increased the keyframes but still doesn't work. Please help:
.grid-item-2 {
grid-column: 1 / span 2;
grid-row: 1;
background-image: url(Building_1.png);
margin-left: 100px;
margin-top: 53px;
width: 90%;
background-repeat: repeat-x;
animation: Buildings 2s linear infinite;
}
#keyframes Buildings {
0% { background-position: 0% 100%; }
25% { background-position: 25% 75%; }
50% { background-position: 50% 50%; }
75% { background-position: 75% 25%; }
100% { background-position: 100% 0; }
}
<div class="grid-item grid-item-2"></div>
The problem with the jumping is that you need to adapt the background image to the size of the div element, which can be hard if you want to have a responsive site. The code below is the best I can come up with, where I loop between -100% and 200%, making the image start outside the element and then end outside the other side of the element, creating the illusion that it continues. I would honestly replace repeat-x with just repeat.
I added a background color just to make the element more visible.
.grid-item-2 {
grid-column: 1 / span 2;
grid-row: 1;
background-image: url("https://picsum.photos/id/737/300/200.jpg");
/* margin-left: 100px;
margin-top: 53px; */
width: 90%;
background-repeat: repeat-x;
background-size: 50% 50%;
animation: Buildings 3s linear infinite;
background-color: #000; /* just to show case the element better */
height: 90vh;
}
#keyframes Buildings {
0% { background-position: -100% 200%; }
100% { background-position: 200% -100%; }
}
<div class="grid-item-2">
</div>
Getting rid of the intermediary keyframes would make it smoother. You only need the frames at 0% and 100%. When you set the animation timing function to linear, it will automatically make sure that all the keyframes that you defined are met. The animation should look something like this...
#keyframes Buildings {
0% {
background-position: 0% 100%;
}
100% {
background-position: 100% 0;
}
}

Slide long image horizontally (full screen)

Could do with some help.
I need to slide a long image horizontally once and then back... I've followed a tutorial here https://css-tricks.com/creating-a-css-sliding-background-effect/ and its all working. My problem is I want the sliding image to be fullscreen (the image height needs to fit the browser viewpoint). Current image is 7676 x 3939. background-size: cover was an option but image is too large so it doesn't fit height-wise. So I'd like half the image (3838px - fullscreen) to show initially then slide to the other half and then back.
Would appreciate some assistance. Below is my code. Thanks.
.wrapper {
overflow: hidden;
}
.sliding-background {
background: url("long-image.jpg") center;
height: 100vh;
width: 7676px;
animation: slide 3s linear 1;
}
#keyframes slide {
0%{
transform: translate3d(0, 0, 0);
}
50%{
transform: translate3d(-3838px, 0, 0);
}
100%{
transform: translate3d(0, 0, 0);
}
}
Try add position relative or absolute to .sliding-background
You could also try animating the background position instead of the element itself. Then you should make your container full screen, like this:
body,
html {
margin: 0;
padding: 0;
}
#wrapper {
overflow: hidden;
}
.sliding-background {
background-image: url("https://upload.wikimedia.org/wikipedia/commons/9/93/Denali_National_Park_Polychrome_Mountains_Wide_17350px.jpg");
background-repeat: repeat-x;
background-size: cover;
height: 100vh;
width: 100vw;
animation: slide 45s linear infinite;
}
#keyframes slide {
0% {
background-position: 0 0;
}
50% {
background-position: 100% 0;
}
100% {
background-position: 0 0;
}
}
See: https://jsfiddle.net/9mLhdy4c/

Strange background-image bug on Chrome and Firefox

My goal is to create a little slideshow, and I already made it here : https://jsfiddle.net/cas1g2ch/2/
Here's the code :
HTML
<div id="first-block">
<div id="background-header">
<div class="bg-wrapper">
<div class="background-img-1"></div>
</div><!--
--><div class="bg-wrapper">
<div class="background-img-2"></div>
</div>
</div>
</div>
CSS
#first-block{
position: relative;
width: 100%;
height: 100vh;
}
#keyframes zoomPicture {
0%{
transform: scale(1.0);
}
50%{
transform: scale(1.1);
}
100%{
transform: scale(1.0);
}
}
#background-header{
position: absolute;
top : 0;
left : 0;
width: 200vw;
height: 100vh;
box-shadow: 0px 1px 1px #333;
}
#background-header > .bg-wrapper
{
width: 100vw;
height: 100vh;
display: inline-block;
float: left;
overflow: hidden;
}
#background-header > .bg-wrapper > div{
width: 100vw;
height: 100vh;
background-attachment: fixed;
animation-duration: 20s;
background-size: cover;
animation-timing-function: ease-in-out;
animation-name: zoomPicture;
animation-iteration-count: infinite;
}
#background-header .background-img-1 {
background-image: url("http://www.hd-wallpaper.images-fonds.com/modules/mg3/albums/Paysages_(landscapes)_Wallpaper_HD/Paysages/Paysage_(landscape)_wallpaper_HD_0025.jpg");
}
#background-header .background-img-2 {
background-image: url("http://unreveunvoyage.fr/wp-content/uploads/2015/04/parc-national-de-banff-paysage-canada.jpg");
}
Right now the slideshow has two pictures, and each picture covers the entire screen size (width : 100vw ; height : 100vh ; background-size : cover).
To display the pictures I used background-image, and the backgrounds are fixed.
Because I cannot animate a background with background-size : cover, I used transform : scale to add a little zoom effect.
The problems :
On Chrome there's a weird Glitch (Chrome 56 on Windows), just use the scrollbar
in the demo to see the problem, here's a video I made that shows the
problem : https://www.youtube.com/watch?v=NHCLBTpxCAs (In this video I chose a high transform: scale value to better recognize the bug)
On Firefox the backgrounds are not fixed, but the pictures are
displayed correctly
Surprisingly it works great on Internet Explorer 11
It also seems to work on mobile
How can I fix this? What is the best workaround?