I have a div with a background image and I'm trying to change its scale infinitely.
I changed the background-size property in the animation but as you can see, there is some noise or vibration when animating. How would I remove it?
.pre-loader {
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') center no-repeat #fff;
background-size: 50%;
animation: loading 5s ease-in-out infinite;
}
#keyframes loading {
0% {
background-size: 50%
}
50% {
background-size: 55%
}
100% {
background-size: 50%
}
}
<div class="pre-loader"></div>
Consider a scale transformation to have a better rendring:
.pre-loader {
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
overflow:hidden;
}
.pre-loader:before {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') center/50% auto no-repeat #fff;
animation: loading 5s ease-in-out infinite;
}
#keyframes loading {
50% {
transform:scale(1.1);
}
}
<div class="pre-loader"></div>
You are centering the background which means applying a background-position equal to 50%. The calculation of this value is related to the background-size so the position is changing slightly when the size is changing creating this bad effect:
If you consider a position using pixel values you will not see this effect:
.pre-loader {
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
overflow:hidden;
}
.pre-loader:before {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') 50px 50px/50% auto no-repeat #fff;
animation: loading 5s ease-in-out infinite;
}
#keyframes loading {
50% {
background-size:55%;
}
}
<div class="pre-loader"></div>
Use transform instead of background-size
.pre-loader {
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') center no-repeat #fff;
background-size: 50%;
animation: loading 5s ease-in-out infinite;
}
#keyframes loading {
50% {
transform: scale(1.2);
}
100% {
transform: initial;
}
}
<div class="pre-loader"></div>
There is nothing wrong with your code, the problems lays in the CSS. I think there is a performance issue in your animation with:
#keyframes loading {
0% {
background-size: 50%
}
50% {
background-size: 55%
}
100% {
background-size: 50%
}
The animation will relocate every single pixel from every image. So that will be a bit heavy for the browser to render I think.
Also your animation time with animation: loading 5s ease-in-out infinite; is a factor why its making noises. With the animation time of 5 seconds, it becomes clear that each pixel is reloaded.
If you change this time to 1s, you'll find that it runs smoother as the time between animations goes by faster.
But since the 5 seconds should persist, the simplest solution is to add the code snippets from #FĂ©lix or #TemaniAfif answer into your code which are really 2 great answers to your question.
Related
I want to infinite Scroll Background image animate. How can I set it just go upwards continuously, not come back down? still, it gives a jerk.
How it is possible? Please help anyone know it.
I have a link:
http://herinshah.com/wp/fortiflex/5-2/
CSS:
.et_pb_section.landing-page .et_pb_column_3_5 {
background-color: #f6eb00;
margin-right: 1%;
padding: 0 10px;
height: 100vh;
background-image: url(images/ragazzi-logo.png);
background-position: 0 0;
background-size: cover;
-webkit-animation: upward 15s linear infinite;
animation: upward 15s linear infinite;
border-right: 4px solid #000;
display: block;
background-repeat: repeat-y;
}
#-webkit-keyframes upward {
to {
background-position: 0 0;
}
from {
background-position: 0 2174px;
}
}
#keyframes upward {
to {
background-position: 0 0;
}
from {
background-position: 0 2174px;
}
}
You need to wrap a div inside a div. Here is the working fiddle for the same
HTML
<div class="main">
<div class="holder"></div>
</div>
CSS
*{
margin:0;
padding:0
}
.main {
height: 100vh;
overflow: hidden;
}
.holder {
height: 200vh;
-webkit-animation: upwards 2.5s linear infinite;
animation: upward 2.5s linear infinite;
background: url(http://herinshah.com/wp/fortiflex/wp-content/themes/Divi/images/ragazzi-logo.png) center yellow;
background-size: 100% 50%;
}
#-webkit-keyframes upward {
from {
background-position: 0% 0%;
}
to {
background-position: 0% -100%;
}
}
#keyframes upward {
from {
background-position: 0% 0%;
}
to {
background-position: 0% -100%;
}
}
I felt so compelled to answer this because I've done something similar :before (pun intended) and your skipping animation was giving me cancer.
You're gonna need to mess around with the pseudo :after element and get the height right. This should get you started.
Also your image isn't cropped perfectly right, so fix that and you'll be good to go.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body onload="onloaded()">
<div class="foo_section">
<div class="foo_container">
<img class="foo_image" src="http://herinshah.com/wp/fortiflex/wp-content/themes/Divi/images/ragazzi-logo.png" />
</div>
</div>
</body>
</html>
.foo_section {
width: 100vw;
height: 100vh;
position: fixed;
min-height: 400px;
}
.foo_container {
width: 100%;
position: relative;
animation: infiniteScrollBg 10s infinite linear;
}
.foo_container:after {
content: "";
height: 500%;
width: 100%;
position: absolute;
left: 0;
top: 0;
background-color: #f6eb00;
background-image: url('http://herinshah.com/wp/fortiflex/wp-content/themes/Divi/images/ragazzi-logo.png');
background-size: 100% 20%;
}
.foo_image {
width: 100%;
}
#-webkit-keyframes infiniteScrollBg {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(-200%);
}
}
Codepen
I see you're using Elegant Themes too. <3 Divi builder
I suggest you to have two div tags with the same background. Then, animate the same div and play with positioning of the divs and animate to make it look continuously scrolling up.
.container{
width:600px;
height:400px;
background-color:yellow;
margin:0 auto;
position:relative;
overflow:hidden;
}
.bg{
width:100%;
height:400px;
background-repeat:no-repeat;
background-size:contain;
position:absolute;
bottom:0;
}
.bg.bg1{
transform: translate(0,0);
animation: upward 3s linear infinite;
}
.bg.bg2{
transform: translate(0,100%);
animation: upward2 3s linear infinite;
}
#keyframes upward {
to {
transform: translate(0,-100%);
}
from {
transform: translate(0, 0);
}
}
#keyframes upward2 {
to {
transform: translate(0,0);
}
from {
transform: translate(0,100%);
}
}
Here's how I would do it. my codepen.
I have a div with background image and I want to make effect of infinite scrolling.
I'm trying to do it with transform. The problem which I am facing is the when the animation reach a certain point (I guess when width of bg div is reached with transform) the animation snaps back to the beginning of the image.
Is there a way to avoid this issue?
As reference I used this article
HTML
<div class="holder">
<div class="bg"></div>
</div>
CSS
.holder {
height: 60%;
width: 100%;
position: absolute;
bottom: 40%;
left: 0;
}
.bg {
background-image: url('bg.jpg');
background-repeat: repeat-x;
background-size: auto 100%;
position: absolute;
left: 0;
bottom: 0;
width: 22416px; // width of image 3 times
height: 70%;
transform: translateZ(1px);
animation: slide 60s linear infinite;
}
My animation
#keyframes slide{
0%{
transform: translate3d(0, 0, 0);
}
100%{
transform: translate3d(-7472px, 0, 0); // width of image
}
}
I've got this sample sprite grid sheet that I need to run through and animate. I am able to reach a certain point but struggling to make it perfect. The animation is not that smooth and additionally, the image is not aligned properly. During the animation, you can see image elements not centered with other elements in the view. Here is my HTML and CSS3 code so far.
.hi {
width: 910px;
height: 340px;
background-image: url("https://simba-heroku.imgix.net/animation-homepage-tablet-retina.jpg?auto=format,compress");
position: relative;
-webkit-animation: playv 12s steps(6) infinite, playh 2s steps(4) infinite;
}
#-webkit-keyframes playv {
0% { background-position-y: 0px; }
100% { background-position-y: 100%; }
}
#-webkit-keyframes playh {
0% { background-position-x: 0px; }
100% { background-position-x: 100%; }
}
<div class="hi">
</div>
Fiddle: http://jsfiddle.net/bf5ckdv9/
I have added a background dimension style, and rearranged some of your properties
the result is almost ok; but your sprite grid seems to be out of order
.hi {
width: 910px;
height: 340px;
background-image: url("https://simba-heroku.imgix.net/animation-homepage-tablet-retina.jpg?auto=format,compress");
position: relative;
animation: playh 2s steps(5) infinite, playv 10s steps(5) infinite;
border: solid 1px blue;
background-size: 500% 500%;
background-repeat: no-repeat;
}
#keyframes playv {
0% { background-position-y: 0px; }
100% { background-position-y: 125%; }
}
#keyframes playh {
0% { background-position-x: 0%; }
100% { background-position-x: 125%; }
}
<div class="hi">
</div>
I'm trying to do some interactive map, where I'm using two very large images (3200x800 and 4096x1024 pixels). Problem is, that Chrome decode image with clouds every frame... so performance is really poor (example in snippet).
Found similar problem here, but didn't help. I'm using Chrome 43 (64-bit) on Linux Mint 17.1 (64-bit). I also tried Firefox and without problem...
html, body {
height: 100%;
}
body {
margin: 0;
overflow: hidden;
}
div {
position: absolute;
width: 3200px;
height: 1800px;
background: url('http://i.imgur.com/p1Jf722.png'), url('http://i.imgur.com/zUkgN3j.jpg');
animation: clouds 200s linear infinite;
transition: 5s;
left: 0;
top: 0;
}
#keyframes clouds {
from { background-position: 0 0, left top; }
to { background-position: 4096px 0, left top; }
}
body:hover > div {
left: -500px;
top: -250px;
}
<div></div>
Using a pseudo element and transform still uses a lot of CPU, but it is quite smoother. And it absolutely eliminates the image decodes.
I think that Chrome is using a single buffer for a div background. When you change the relative positions of the 2 images in this buffers, it becomes invalid and has to be rendered decoded again. Probably FF can allocate an intermediate buffer for every image, even if used in the same background
html, body {
height: 100%;
}
body {
margin: 0;
overflow: hidden;
}
div {
position: absolute;
width: 3200px;
height: 1800px;
background: url('http://i.imgur.com/zUkgN3j.jpg');
transition: 5s;
left: 0;
top: 0;
background-position: left top;
transform: translateZ(0px);
}
div:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: url('http://i.imgur.com/p1Jf722.png');
animation: clouds 200s linear infinite;
transition: 5s;
left: 0;
top: 0;
transform: translateZ(0px);
}
#keyframes clouds {
from { background-position: 0 0; }
to { background-position: 4096px 0; }
}
body:hover > div {
left: -500px;
top: -250px;
}
<div></div>
There are probably multiple ways to do improve performance here, but the lowest hanging fruit is just to offload everything onto the GPU by adding a non-distorting transform to your div. Voila, no more image decodes.
html, body {
height: 100%;
}
body {
margin: 0;
overflow: hidden;
}
div {
position: absolute;
width: 3200px;
height: 1800px;
background: url('http://i.imgur.com/p1Jf722.png'), url('http://i.imgur.com/zUkgN3j.jpg');
animation: clouds 200s linear infinite;
transition: 5s;
left: 0;
top: 0;
transform: translateZ(0);
}
#keyframes clouds {
from { background-position: 0 0, left top; }
to { background-position: 4096px 0, left top; }
}
body:hover > div {
left: -500px;
top: -250px;
}
<div></div>
So I got this Fullscreen Background Image Slideshow from tympanus :) You can definitely see the codes on the site linked above... now I do not want it to be taking the whole page... I want to add margins all over... I've been trying to do it but no avail. I tried reducing the size of the background image into lesser percent but it's still not proportioned...
How do I add an equal padding to the slideshow? :(
.cb-slideshow li span {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
color: transparent;
background-size: cover;
background-position: 50% 50%;
background-repeat: none;
opacity: 0;
z-index: 0;
animation: imageAnimation 36s linear infinite 0s;
}
I think the absolute simplest way is to do like this:
.cb-slideshow li span {
left: 5%; // alter as you like
top: 5%; // alter as you like
width: 90%; // alter as you like
height: 90%; // alter as you like
position: absolute;
color: transparent;
background-size: cover;
background-position: 50% 50%;
background-repeat: none;
opacity: 0;
z-index: 0;
animation: imageAnimation 36s linear infinite 0s;
}