After following the instructions here: https://davidwalsh.name/background-animation-css
I can make the picture move, but I cannot figure out how to make it responsive. Any ideas on how to make this possible? I have added following css code:
#keyframes animatedBackground{
from {background-position: 0 0;}
to {background-position: -1920px 0;}
}
#animate-area{
width: 560px;
height: 400px;
background-image: url("images/japan.jpg");
background-position: 0px 0px;
background-repeat: repeat-x;
animation: animatedBackground 40s linear infinite;
}
Within the demo, the width of <div id="animate-area"> is explicitly set to 560px. Try setting it to width: auto;. This should scale the div width to that of it's container/parent.
Related
Why this isn't working? What am I doing wrong?
CSS
#-webkit-keyframes test {
0% {
background-image: url('frame-01.png');
}
20% {
background-image: url('frame-02.png');
}
40% {
background-image: url('frame-03.png');
}
60% {
background-image: url('frame-04.png');
}
80% {
background-image: url('frame-05.png');
}
100% {
background-image: url('frame-06.png');
}
}
div {
float: left;
width: 200px;
height: 200px;
-webkit-animation-name: test;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: linear;
}
DEMO
http://jsfiddle.net/hAGKv/
Updated for 2020: Yes, it can be done! Here's how.
Snippet demo:
#mydiv{ animation: changeBg 1s infinite; width:143px; height:100px; }
#keyframes changeBg{
0%,100% {background-image: url("https://i.stack.imgur.com/YdrqG.png");}
25% {background-image: url("https://i.stack.imgur.com/2wKWi.png");}
50% {background-image: url("https://i.stack.imgur.com/HobHO.png");}
75% {background-image: url("https://i.stack.imgur.com/3hiHO.png");}
}
<div id='mydiv'></div>
Background image [isn't a property that can be animated][1] - you can't tween the property.
Original Answer: (still a good alternative)
Instead, try laying out all the images on top of each other using position:absolute, then animate the opacity of all of them to 0 except the one you want repeatedly.
It works in Chrome 19.0.1084.41 beta!
So at some point in the future, keyframes could really be... frames!
You are living in the future ;)
Works for me.
Notice the use of background-image for transition.
#poster-img {
background-repeat: no-repeat;
background-position: center;
position: absolute;
overflow: hidden;
-webkit-transition: background-image 1s ease-in-out;
transition: background-image 1s ease-in-out;
}
This is really fast and dirty, but it gets the job done: jsFiddle
#img1, #img2, #img3, #img4 {
width:100%;
height:100%;
position:fixed;
z-index:-1;
animation-name: test;
animation-duration: 5s;
opacity:0;
}
#img2 {
animation-delay:5s;
-webkit-animation-delay:5s
}
#img3 {
animation-delay:10s;
-webkit-animation-delay:10s
}
#img4 {
animation-delay:15s;
-webkit-animation-delay:15s
}
#-webkit-keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
#keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
I'm working on something similar for my site using jQuery, but the transition is triggered when the user scrolls down the page - jsFiddle
I needed to do the same thing as you and landed on your question. I ended up taking finding about the steps function which I read about from here.
JSFiddle of my solution in action (Note it currently works in Firefox, I'll let you add the crossbrowser lines, trying to keep the solution clean of clutter)
First I created a sprite sheet that had two frames. Then I created the div and put that as the background, but my div is only the size of my sprite (100px).
<div id="cyclist"></div>
#cyclist {
animation: cyclist 1s infinite steps(2);
display: block;
width: 100px;
height: 100px;
background-image: url('../images/cyclist-test.png');
background-repeat: no-repeat;
background-position: top left;
}
The animation is set to have 2 steps and have the whole process take 1 second.
#keyframes cyclist {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -202px; //this should be cleaned up, my sprite sheet is 202px by accident, it should be 200px
}
}
Thiago above mentioned the steps function but I thought I'd elaborate more on it. Pretty simple and awesome stuff.
Your code can work well with some adaptations :
div {
background-position: 50% 100%;
background-repeat: no-repeat;
background-size: contain;
animation: animateSectionBackground infinite 240s;
}
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
Here is the explanation of the percentage to suit your situation:
First you need to calculate the "chunks". If you had 8 differents background, you need to do :
100% / 8 = 12.5% (to simplify you can let fall the decimals) => 12%
After that you obtain that :
#keyframes animateSectionBackground {
00% { background-image: url(/assets/images/bg-1.jpg); }
12% { background-image: url(/assets/images/bg-2.jpg); }
25% { background-image: url(/assets/images/bg-3.jpg); }
37% { background-image: url(/assets/images/bg-4.jpg); }
50% { background-image: url(/assets/images/bg-5.jpg); }
62% { background-image: url(/assets/images/bg-6.jpg); }
75% { background-image: url(/assets/images/bg-7.jpg); }
87% { background-image: url(/assets/images/bg-8.jpg); }
}
If you execute this code, you will see the transition will be permanantly. If you want the backgrounds stay fixed while a moment, you can do like this :
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
That mean you want :
bg-1 stay fixed from 00% to 11%
bg-2 stay fixed from 12% to 24%
etc
By putting 11%, the transtion duration will be 1% (12% - 11% = 1%).
1% of 240s (total duration) => 2.4 seconds.
You can adapt according to your needs.
The linear timing function will animate the defined properties linearly. For the background-image it seems to have this fade/resize effect while changing the frames of you animation (not sure if it is standard behavior, I would go with #Chukie B's approach).
If you use the steps function, it will animate discretely. See the timing function documentation on MDN for more detail. For you case, do like this:
-webkit-animation-timing-function: steps(1,end);
animation-timing-function: steps(1,end);
See this jsFiddle.
I'm not sure if it is standard behavior either, but when you say that there will be only one step, it allows you to change the starting point in the #keyframes section. This way you can define each frame of you animation.
Like the above stated, you can't change the background images in the animation. I've found the best solution to be to put your images into one sprite sheet, and then animate by changing the background position, but if you're building for mobile, your sprite sheets are limited to less than 1900x1900 px.
I needed to do the same thing recently. Here's a simple implementation
#wrapper { width:100%; height:100%; position:relative; }
#wrapper img { position:absolute; top:0; left:0; width:100%; height:auto; display:block; }
#wrapper .top { animation:fadeOut 2s ease-in-out; animation-fill-mode:forwards; }
#keyframes fadeOut {
0% { opacity:1; }
100% { opacity:0; }
}
<div id="wrapper">
<img src="img1.jpg" class="top" style="z-index:2;">
<img src="img2.jpg" style="z-index:1;">
</div>
You can use animated background-position property and sprite image.
You can follow by this code:
#cd{
position: relative;
margin: 0 auto;
height: 281px;
width: 450px;
}
#cf img{
left: 0;
position: absolute;
-moz-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
#cf img.top:hover{
opacity: 0;
}
<div id="cf">
<img class="button" src="Birdman.jpg" />
<img src="Turtle.jpg" class="top" />
</div>
You can use the jquery-backstretch image which allows for animated slideshows as your background-images!
https://github.com/jquery-backstretch/jquery-backstretch
Scroll down to setup and all of the documentation is there.
Well I can change them in chrome. Its simple and works fine in Chrome using -webkit css properties.
Hi I use ionic cdn in my web page
https://vipage.vivbook.com/lianaox/
Current site doesn't have ion-content tag.
The first problem is the screen is not scroll able.
I got that it is because of I didn't use ion-content
I add ion-content but the problem is how to use this animated css to the background of the page (not background of the card!)?
ion-content{
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
}
#keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
And is there anyway to enable scrollbar without using ion-content?
If you're using Ionic 4#5.
ion-content {
--background: *whatever you want here*
}
Or,
ion-content {
--background: transparent;
background: linear-gradient(*whatever you want here*);
}
I am creating an interactive touchscreen display using a program called Intuiface and have created some background tiles/squares that I want to make look 'alive' by transitioning slowly between colours.
I have used a linear-gradient transition in CSS to do it but the problem is that the transition looks choppy. The program is running 12 visible tiles (it is a very large touchscreen).
I have tried using fewer colours and running on more powerful GPUs (I think it is CPU run anyway) but this hasn't helped.
body {
width: 100wh;
height: 90vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
animation: Gradient 15s ease infinite;
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
At the moment the animations are noticeably choppy. I would like the transition to be much smoother. Does anyone know how I can achieve this?
Here is the code snippet.
body {
width: 100wh;
height: 90vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
animation: Gradient 15s ease infinite;
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
<html>
<body>
</body>
</html>
Animating background-* properties can be resource intensive - you can try animating transform for relatively better performance - see demo below using traslate for the animation:
body {
margin: 0;
}
div {
height: 100vh;
overflow: hidden;
}
div:after {
content: '';
display: block;
width: 400vw;
height: 400vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
animation: gradient 15s ease infinite;
}
#keyframes gradient {
50% {
transform: translate(-300vw, -300vh);
}
}
<div></div>
Since your animation lasts 15 seconds, trying to run it at full 60fps would mean calculating 15*60 = 900 frames.
Since the difference between a frame and the next is quite small, you can make the CPU work quite less asking for a stepped animation, for instance with steps(75)
It could be also good to set slight delays between animations, so that they don't execute at the same time
body {
width: 100wh;
height: 90vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
animation: Gradient 15s infinite steps(75);
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
<html>
<body>
</body>
</html>
We need to create a screensaver where image should roll over again and again continuously to the left. We coded as shown below.
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style>
.animator {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/33/Jordansallotments.jpg);
animation: move-background 2s linear infinite;
position: absolute;
width: 100%;
height: 100%;
}
html,
body {
position: relative;
width: 100%;
height: 100%;
}
#keyframes move-background {
0% {
background-position: 0%, 0%;
}
100% {
background-position: 100%, 0%;
}
}
</style>
</head>
<body>
<div class="animator"></div>
</body>
</html>
The image is rolling over again and again as expected but every 2seconds, we are getting flickering effect. Please see the demo here.
As a fiddle
Can any one please help me to fix this or is there any way to achieve the effect of rolling one image over and over continuously using javascript?
I tried with javascript as below.
<script type="text/javascript">
var bdg_img = document.getElementById('bdgimg');
var animate;
function moveRight()
{
bdg_img.style.left = bdg_img.style.left || 0;
bdg_img.style.left = parseInt(bdg_img.style.left) + 10 + 'px';
animate = setTimeout(moveRight,40); // call moveRight in 20msec
}
moveRight();
</script>
But this is only moving the image to right. The image is not rolling over.
The percentage value in background-position: xxx% is relative to the element's size, not to your actual image's.
So if you want to keep the original background-image-size, you will have to set this background-position relative to your media's size:
.animator {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/33/Jordansallotments.jpg);
background-position: 0% 50%;
animation: move-background 2s linear infinite;
width: 100vw;
height: 100vh;
}
#keyframes move-background {
to {
/* the image is 1225*800px */
background-position: -1225px 50%;
}
}
<div class="animator"></div>
Also note that when you do
background-position: 100%, 0%;
You are actually setting two background-position rules, which would be used only if you did set two background-image rules, and is indeed a short-hand for :
background-position-x: 100%, 0%;
background-position-y: 100%, 0%;
you can use very long animation time and repeat background to produce the effect.
*this animation play more than 10day (and may flicker once), but you can make it longer if you want.
*of course you can do the same thing (modify the style) in javascript by setInterval or alike. and have real infinity duration (at least until it reach numeric limit).
.canvas{
width: 300px;
height: 100px;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/3/33/Jordansallotments.jpg);
background-size: auto 100%;
background-repeat: repeat-x;
animation: move-background 1000000s linear infinite;
}
#keyframes move-background {
0% {
background-position: 0 0;
}
100% {
background-position: -20000000px 0;
}
}
<div class="canvas"></div>
I have several animations on my site that I just realized do not even show up in Firefox or Internet Explorer. I have the background-image within the keyframes. I do this because I have different images in different percentages with the animation.
Why doesn't the background-image display within the keyframes in Firefox and Internet Explorer and is there a way to make this work?
As per the specs, background-image is not an animatable or a transitionable property. But it does not seem to say anything about what or how the handling should be when it is used as part of transition or animation. Because of this, each browser seem to be handling it differently. While Chrome (Webkit) is displaying the background image, Firefox and IE seem to do nothing.
The below quote found in an article at oli.jp provides some interesting information:
While CSS Backgrounds and Borders Module Level 3 Editor’s Draft says “Animatable: no” for background-image at the time of writing, support for crossfading images in CSS appeared in Chrome 19 Canary. Until widespread support arrives this can be faked via image sprites and background-position or opacity. To animate gradients they must be the same type.
On the face of it, it looks like Firefox and IE are handling it correctly while Chrome is not. But, it is not so simple. Firefox seems to contradict itself when it comes to how it handles transition on background image as opposed to animation. While transitioning background-image, it shows up the second image immediately (hover the first div in the snippet) whereas while animating, the second image doesn't get displayed at all (hover the second div in the snippet).
So, conclusion is that it is better to not set background-image inside keyframes. Instead, we have to use background-position or opacity like specified # oli.jp.
div {
background-image: url(https://placehold.it/100x100);
height: 100px;
width: 100px;
margin: 10px;
border: 1px solid;
}
div:nth-of-type(1) {
transition: background-image 1s ease;
}
div:nth-of-type(1):hover {
background-image: url(https://placehold.it/100/123456/ffffff);
}
div:nth-of-type(2):hover {
animation: show-img 1s ease forwards;
}
#keyframes show-img {
to {
background-image: url(https://placehold.it/100/123456/ffffff);
}
}
<div></div>
<div></div>
If you have multiple images that should be shown at different percentages within the keyframe then it would be a better idea to add all those images on the element at start and animate their position like in the below snippet. This works the same way in Firefox, Chrome and IE.
div {
background-image: url(https://placehold.it/100x100), url(https://placehold.it/100/123456/ffffff);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: 0px 0px, 100px 0px;
height: 100px;
width: 100px;
margin: 10px;
border: 1px solid;
}
div:hover {
animation: show-img 1s steps(1) forwards;
}
#keyframes show-img {
to {
background-position: -100px 0px, 0px 0px;
}
}
<div></div>
Or, like in the below snippet. Basically each image is the same size as the container as background-size is set as 100% 100% but only one image is shown at any given time because of them being the same size as container. Between 0% to 50% the first image is shown because it is at 0px,0px (left-top) whereas the second image is at 100px,0px (outside the right border). At 50.1%, the first image is at -100px,0px (outside left border) and second image is at 0px,0px and so it is visible.
div {
background-image: url(https://picsum.photos/id/0/367/267), url(https://picsum.photos/id/1/367/267);
background-size: 100% 100%; /* each image will be 100px x 100px */
background-repeat: no-repeat;
background-position: 0px 0px, 100px 0px;
height: 100px;
width: 100px;
margin: 10px;
border: 1px solid;
animation: show-img 5s ease forwards;
}
#keyframes show-img {
0%, 50%{
background-position: 0px 0px, 100px 0px; /* initially 1st image will be shown as it it as 0px 0px */
}
50.1%, 100% {
background-position: -100px 0px, 0px 0px; /* at 50.1% 2nd image will be shown as it it as 0px 0px */
}
}
<div></div>