Animating two circles to meet exactly in the middle - html

So I'm aiming to have two circles meet from either side of the screen and meet in the middle to perform the second half of the animation (scaling and opacity change).
But by setting the initial keyframe and last using vw they don't meet in the middle - since the vw value is relative to the left side of the div and not the centre (I have used vw as I need this to be responsive). So, what happens is that the left sides of the circle meet in the centre.
Does anyone know a simple fix to this using just css? I am newish to coding, so if the answer is obvious I apologise.
Here is my code:
#keyframes left {
0% {
transform: translate3d(0vw, 50%, 0) scale3d(1, 1, 1);
opacity: 50%;
animation-timing-function: ease-in;
}
60% {
transform: translate3d(50vw, 50%, 0) scale3d(1, 1, 1);
opacity: 50%;
animation-timing-function: ease-out;
}
100% {
transform: translate3d(50vw, 50%, 0) scale3d(2, 2, 1);
opacity: 0%;
animation-timing-function: ease-out;
}
}
#keyframes right {
0% {
transform: translate3d(100vw, 50%, 0) scale3d(1, 1, 1);
opacity: 50%;
animation-timing-function: ease-in;
}
60% {
transform: translate3d(50vw, 50%, 0) scale3d(1, 1, 1);
opacity: 50%;
animation-timing-function: ease-out;
}
100% {
transform: translate3d(50vw, 50%, 0) scale3d(2, 2, 1);
opacity: 0%;
animation-timing-function: ease-out;
}
}
.circleleft {
overflow: hidden;
position: absolute;
background: white;
border-radius: 50%;
width: 500px;
height: 500px;
animation: left 2s;
animation-fill-mode: forwards;
}
.circleright {
overflow: hidden;
position: absolute;
background: white;
border-radius: 50%;
width: 500px;
height: 500px;
animation: right 2s;
animation-fill-mode: forwards;
}
<div style="width:100vw; height:100vh; background-color:#87827E">
<div class="circleleft"></div>
<div class="circleright"></div>
</div>
You can see it in use here too: https://ruairimadine.co.uk/sudoroux

One trick is to initially position both circles in the center and the animation/translation will offset them from the left or right.
I optimized the code to only use pseudo-elements and make it easier to understand:
body {
margin: 0;
height: 100vh;
background-color: #87827E;
overflow: hidden;
position:relative;
}
body::before,
body::after{
content:"";
position: absolute;
top: calc(50% - 25vmin);
left:calc(50% - 25vmin);
background: white;
opacity: 50%;
border-radius: 50%;
width: 50vmin;
height: 50vmin;
animation: move 2s forwards;
}
/* 50vw : half the screen width | 25vmin half the circle width*/
body::before { transform:translateX(calc( 50vw + 25vmin)); }
body::after { transform:translateX(calc(-50vw - 25vmin)); }
#keyframes move {
60% {
transform: translateX(0) scale(1);
opacity: 50%;
}
100% {
transform: translateX(0) scale(2);
opacity: 0%;
}
}

In this example the circles size is stored in the root variable --circle-size: 100px;. So the circles can be centered with top and left easily. The animation uses the properties left (position), opacity and transform: scale (scaling).
setTimeout(()=>{
document.querySelector('.circle-left').classList.add('circle__animated');
document.querySelector('.circle-right').classList.add('circle__animated');
}, 1000);
:root{
--circle-size: 100px;
}
.circle{
position: absolute;
width: var(--circle-size);
height: var(--circle-size);
border-radius: 50%;
top: calc(50% - var(--circle-size)/2);
}
.circle.circle-left{
background: red;
left: 0;
animation: left 2s;
animation-fill-mode: forwards;
}
.circle.circle-right{
background: green;
left: calc(100% - var(--circle-size));
animation: right 2s;
animation-fill-mode: forwards;
}
#keyframes left {
0% {
left: 0;
opacity: 1;
transform: scale(1);
animation-timing-function: ease-in;
}
60% {
left: calc(50% - var(--circle-size)/2);
opacity: 0.5;
transform: scale(1);
animation-timing-function: ease-out;
}
100% {
left: calc(50% - var(--circle-size)/2);
opacity: 0;
transform: scale(5);
animation-timing-function: ease-out;
}
}
#keyframes right {
0% {
left: calc(100% - var(--circle-size));
opacity: 1;
transform: scale(1);
animation-timing-function: ease-in;
}
60% {
left: calc(50% - var(--circle-size)/2);
opacity: 0.5;
transform: scale(1);
animation-timing-function: ease-out;
}
100% {
left: calc(50% - var(--circle-size)/2);
opacity: 0;
transform: scale(5);
animation-timing-function: ease-out;
}
}
<div style="position: absolute; top:0; left: 0; width:100vw; height:100vh; background-color:#87827E; padding: 0; margin: 0; overflow: hidden;">
<div class="circle circle-left"></div>
<div class="circle circle-right"></div>
</div>

Related

Center align rotating SVG in Loader CSS

I am trying to animate a SVG from 0deg to 360deg. But if i use the transform: rotate property then the svg loses its position and its not centre aligned when the browser resizes. I used transform-origin to 50%. But the svg loses its position.
HTML :
<div id="hexagon-spinner">
<Hexagon className="hexagon-loader" viewBox="0 0 65.103 75.174" />
</div>
#hexagon-spinner {
position: fixed;
width: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.7);
z-index: 9999;
}
.hexagon-loader {
animation-name: spin;
animation-duration: 0.8s;
/* Things added */
animation-iteration-count: infinite;
transform-origin: -50% 50%;
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
}
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
First of all, when it is 100%, you should define 360 degrees, not 359 degrees.
100% {
transform: rotate(359deg); // ->> 360deg
}
What to do about the average,
#keyframes spin {
0% {
transform: rotate(0deg);
transform-origin: -50% 50%;
}
100% {
transform: rotate(360deg);
transform-origin: -50% 50%;
}
}
Finally,
If we need to shorten the code (since it will start with 0deg by default), if we enter only the parameter 100%, there will be no problem.
#keyframes spin {
100% {
transform: rotate(360deg);
transform-origin: -50% 50%;
}
}
Simple Code Snippet
#keyframes spin {
100% {
transform: rotate(360deg);
transform-origin: -50% 50%;
}
}
div {
position: absolute;
top: 50%;
left: 50%;
animation-name: spin;
animation-duration: 0.8s;
/* Things added */
animation-iteration-count: infinite;
transform-origin: -50% 50%;
}
<div>LOADING</div>
#hexagon-spinner {
position: fixed;
width: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.7);
z-index: 9999;
display: flex;
align-items:center;
justify-content: center;
}
.hexagon-loader {
background-color: purple;
height: 40px;
width: 40px;
animation-name: spin;
animation-duration: 0.8s;
/* Things added */
animation-iteration-count: infinite;
display: inline-block;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
}
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
<div id="hexagon-spinner">
<div class="hexagon-loader"></div>
</div>
When we shift the element with the translate (to center it) we naturally distort its center. Therefore it will not work properly.
I suggest a solution for this. (flexbox) is to use. You will see an example below.
Note: (Don't forget to remove Absolute and Transform Origin features)

How to do 2+ rotations while resetting the origin between each during a keyframe?

I try to do an animated box that will unfold itself on the page load.
I have a panel lifted up. I try to rotate it 90deg to the ground, and after, I would want to lift it up again based on the other edge 90deg.
I tried to change the origin (transform-origin: top) but it change the origin to the original origin. I had to add 2 translation to position it at the right place but it create a bump. The edge on the ground don't stick on the ground.
Here's my current fiddle: https://jsfiddle.net/hbnta1uj/2/
I also tried without modifying the origin but I still get a bump:
#keyframes slideFront2 {
0% {
transform: rotateX(-0deg);
}
50% {
transform: rotateX(-90deg);
}
100% {
transform: rotateX(-180deg) translateZ(-100px) translateY(100px);
}
}
I have another idea where I position the second panel flat already and I hide it (opacity 0) and at 50% when the first panel is flat I show the second and just 90deg it.
But I would want to know for more complex animations if there's a way to do it the way I describe it, by always start at the new position the new transformation?
Thanks
I would consider an animation on the container to make it easier where you only need one keyframe:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.container {
width: 90%;
margin: auto;
height: 100vh;
background-color: rgb(194, 194, 194);
}
.progressbar-wrapper {
width: 300px;
height: 100px;
top: calc(50% - 50px);
left: calc(50% - 150px);
position: absolute;
transform-style: preserve-3d;
transform: rotateX(-20deg) rotateY(-30deg);
}
.progressbar {
width: 100%;
height: 100%;
transform-origin: bottom;
animation: 0.5s ease-out 1 slideFront forwards;
transform-style: preserve-3d;
}
.side {
width: 100%;
height: 100%;
background-color: rgba(254, 254, 254, 0.3);
position: absolute;
top: 0;
left: 0;
}
#keyframes slideFront {
100% {
transform: rotateX(-90deg);
}
}
.bottom {
box-shadow: 10px 10px 50px 5px rgba(90, 90, 90, 0.7);
}
.back {
animation: 1s ease-out 0.5s 1 slideFront forwards;
transform-origin: top;
}
<div class="container">
<div class="progressbar-wrapper">
<div class="progressbar">
<div class="side back">
</div>
<div class="side bottom">
</div>
</div>
</div>
</div>
The thing I discover is that the order matter in the translate function. Everything is executed left to right so the origin of the rotation will be relative to the current position of the element if you execute everything left to right (Here's 2 boxes getting the same rotation translation but the order differ: https://codepen.io/anon/pen/oOQGPp)
So in my example, if you do:
50.001% {
transform: rotateX(90deg) translateZ(00px) translatey(100px) ;
transition-timing-function: linear;
}
100% {
transform: rotateX(0deg) translateZ(100px) translatey(00px) ;
transition-timing-function: linear;
}
The rotation will be applied before the translation so the rotation origin will not be the bottom line after the translation but it will be the position without the origin based on the translated part (So it will be the 0% position origin.) CSS will fail to make the path of the animation and it will add a little bump.
But if you do transform: TRANSLATE ROTATE, the rotation will be applied after the translation so the origin of the rotation will be related to the position with the translation. This is how I was able to rotate the item without getting the little bump bug.
Here's the full fixed css. You can run it in my original jsfiddle to see the result
* {
box-sizing: inherit;
margin: 0;
}
html {
box-sizing: border-box;
}
.container {
width: 90%;
margin: auto;
height: 100vh;
background-color: rgb(194, 194, 194);
}
.progressbar-wrapper {
width: 300px;
height: 100px;
top: 50%;
left: 50%;
position: absolute;
transform: translate(-50%, -50%);
}
.progressbar {
width: 100%;
height: 100%;
transform-style: preserve-3d;
transform: rotateX(-20deg) rotateY(-30deg);
}
.side {
width: 100%;
height: 100%;
background-color: rgba(254, 254, 254, 0.3);
position: absolute;
top: 0;
left: 0;
}
#keyframes slideBottom {
0% {
transform: rotateX(-0deg);
}
100% {
transform: rotateX(-90deg);
}
}
#keyframes slideFront {
0% {
transform: rotateX(-0deg);
}
50% {
transform: rotateX(-90deg);
}
50.001% {
transform: translateZ(100px) rotateX(90deg);
transition-timing-function: linear;
}
100% {
transform: translateZ(100px) rotateX(0deg) ;
transition-timing-function: linear;
}
}
.bottom {
animation: 0.5s ease-out 0s 1 slideBottom forwards;
box-shadow: 10px 10px 50px 5px rgba(90, 90, 90, 0.7);
transform-origin: bottom;
}
.back {
animation: 1s ease-out 0s 1 slideFront forwards;
transform-origin: bottom;
}

How to make a ring/hoop flip as a ball passes through it?

I am trying to make something like this:
but the ball doesn't seem to pass through the ring, but rather passes across the ring. How can I fix this issue?
body {
height: 50em;
}
.ring {
position: relative;
width: 200px;
height: 100px;
border-radius: 50%;
border: 10px solid #ffcf82;
z-index: 9
}
#keyframes spinner {
0% {
transform: rotateZ(0deg);
}
30% {
transform: rotateZ(0deg);
}
60% {
transform: rotateZ(180deg);
}
}
#keyframes translate {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-370px);
}
}
.ring {
animation-name: spinner;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 5s;
transform-style: preserve-3d;
}
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
background: #14e78e;
margin: 100px;
}
.ball {
animation-name: translate;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 8s;
transform-style: preserve-3d;
}
<div class="ring"></div>
<div class="ball"></div>
I would create the ring using two elements (the bottom and the top part) to be able to adjust the z-index of each one differently:
.ring {
margin-top:80px;
position: relative;
width: 200px;
height: 100px;
}
.ring:before,
.ring:after{
content:"";
position:absolute;
left:0;
right:0;
height:100%;
border: 10px solid #ffcf82;
border-radius:50%;
box-sizing:border-box;
}
.ring:before {
z-index:-1;
clip-path: polygon(0 0, 100% 0, 100% 50%, 0 50%);
}
.ring:after {
z-index:1;
clip-path: polygon(0 100%, 100% 100%, 100% 50%, 0 50%);
}
#keyframes spinner {
0%,50% {
transform: rotate(0deg);
}
100% {
transform: rotate(-180deg);
}
}
#keyframes translate {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-300px);
}
}
.ring:before,
.ring:after{
animation: spinner infinite alternate 4s;
}
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
background: #14e78e;
margin: 60px 80px;
position:relative;
z-index:0;
animation: translate 8s infinite linear;
}
<div class="ring"></div>
<div class="ball"></div>
Another idea in case you need better support than clip-path. The trick is to play with transparent color:
.ring {
margin-top:80px;
position: relative;
width: 200px;
height: 100px;
}
.ring:before,
.ring:after{
content:"";
position:absolute;
left:0;
right:0;
height:100%;
border: 10px solid #ffcf82;
border-radius:50%;
box-sizing:border-box;
}
.ring:before {
z-index:-1;
}
.ring:after {
z-index:1;
border-bottom-color:transparent;
border-right-color:transparent;
}
#keyframes spinner {
0%,50% {
transform: rotate(0deg);
}
100% {
transform: rotate(-180deg);
}
}
#keyframes translate {
0% {
transform: translateY(10px);
}
50% {
transform: translateY(-310px);
}
}
.ring:before,
.ring:after{
animation: spinner infinite alternate 4s;
}
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
background: #14e78e;
margin: 60px 80px;
position:relative;
z-index:0;
animation: translate 8s infinite linear;
}
<div class="ring"></div>
<div class="ball"></div>
You can try to change z-index of ball inside of animation
body {
height: 50em;
}
.ring {
position: relative;
width: 200px;
height: 100px;
border-radius: 50%;
border: 10px solid #ffcf82;
z-index: 9
}
#keyframes spinner {
0% {
transform: rotateZ(0deg);
}
30% {
transform: rotateZ(0deg);
}
60% {
transform: rotateZ(180deg);
}
}
#keyframes translate {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-370px);
z-index: 10;
}
}
.ring {
animation-name: spinner;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 5s;
transform-style: preserve-3d;
}
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
background: #14e78e;
margin: 100px;
position: relative;
}
.ball {
animation-name: translate;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 8s;
transform-style: preserve-3d;
}
<div class="ring"></div>
<div class="ball"></div>
You can use a 3d transform to get automatically this effect.
Rotate the circle in the X axis. Then, there is one part of it that is behind the plane, and another part that is in front of it. The ball is still in the 0 z plane, so it will naturally appear to cross through the circle:
body {
height: 50em;
transform-style: preserve-3d;
}
.ring {
position: relative;
width: 200px;
height: 100px;
border-radius: 50%;
border: 10px solid #ffcf82;
z-index: 9;
margin-top: 100px;
transform: rotateX(50deg) rotateY(0deg) ;
transform-style: preserve-3d;
}
#keyframes spinner {
0%, 30% {
transform: rotateX(50deg) rotateY(0deg);
}
60%, 100% {
transform: rotateX(50deg) rotateY(180deg);
}
}
#keyframes translate {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-370px);
}
}
.ring {
animation-name: spinner;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 5s;
transform-style: preserve-3d;
}
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
background: #14e78e;
margin: 100px;
}
.ball {
animation-name: translate;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 8s;
transform-style: preserve-3d;
}
<div class="ring"></div>
<div class="ball"></div>

How to move an element linearly while rotating with css

When i use transform on one element for translate3d and rotate3d then the element starts to orbit. i want linear motion while rotating.
i have used webkit animations in css
img{height:50px;
width:50px;
animation:tt;
animation-duration:10s;
position:relative;
top:40vh;
left:40vw;}
#keyframes tt
{ 0%{
transform:rotate3d(0,0,0,0) translate3d(0,0,0);
}
50%{
transform:rotate3d(0,0,1,2000deg) translate3d(300px,0,0);
}
}
i wanted it move forward while rotating like a cars tire instead its like a comet or excited electron
You could use the left and right CSS properties, similar example on https://www.w3schools.com/css/css3_animations.asp
I have included the snippet below:
https://codepen.io/mohamedhmansour/pen/bOONQr
img {
height: 50px;
width: 50px;
animation: tt;
animation-duration: 5s;
position: relative;
top: 0;
left: 0;
}
#keyframes tt {
0% {
transform: rotate(0deg);
left: 0px;
}
50% {
transform: rotate(-360deg);
left: 100%;
}
100% {
transform: rotate(0deg);
left: 0px;
}
}
<div class="wrapper">
<img src="http://blog.codepen.io/wp-content/uploads/2012/06/Button-Fill-Black-Small.png" />
</div>
https://codepen.io/mohamedhmansour/pen/bOONQr
You didn't define the 100% state so by default it will be the a transform:none (the default value since no transform is defined on the element) which is creating the issue. You should define it and use a bigger value for the angle by keeping the same axis to keep your element on the orbit:
.img {
height: 50px;
width: 50px;
animation: tt linear 10s;
position: relative;
top: 40vh;
left: 40vw;
background:red;
}
#keyframes tt {
0% {
transform: rotate3d(0, 0, 0, 0) translate3d(0, 0, 0);
}
50% {
transform: rotate3d(0, 0, 1, 2000deg) translate3d(100px, 0, 0);
}
100% {
transform: rotate3d(0, 0, 1, 4000deg) translate3d(100px, 0, 0);
}
<div class="img"></div>
And if you want a linear animation simply do like this (translation before rotation):
.img {
height: 50px;
width: 50px;
animation: tt linear 5s forwards;
position: relative;
top: 40vh;
left: 40vw;
background:red;
}
#keyframes tt {
0% {
transform: translateX(0) rotate(0);
}
100% {
transform: translateX(100px) rotate(360deg);
}
<div class="img"></div>
You can try this:
img{
height: 50px;
width: 50px;
position: absolute;
top:40vh;
left:40vw;
-webkit-animation: spinner 10s linear infinite;
left: 0;
}
#-webkit-keyframes spinner{
50%{
-webkit-transform: rotate(1440deg);
left: calc(100% - 200px);
}
}
<img src="https://www.gstatic.com/webp/gallery/4.sm.jpg">

CSS animation jumps

Sorry, I'm new to css animations so maybe it's studpid ;) So I got a overlay div I want to animate from top to bottom (fixed at top) and then scale down (fixed at the bottom) but the animations jumps some sequences. I really don't know why. here is a fiddle https://jsfiddle.net/mzd7rqqL/
I think you can see what I try to achieve!
CSS
.overlay {
background: #00b2c0;
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
z-index: 1;
-webkit-animation: infinite 2s;
animation: infinite 2s;
.off {
width: 0;
height: 0;
animation: none !important;
-webkit-animation: none !important;
}
}
#keyframes rolldown {
0% {transform: scaleY(0); transform-origin: left top;}
50% { transform: scaleY(1); }
100% {transform: scaleY(0); transform-origin: left bottom;}
}
.rolldown {
-webkit-animation-name: rolldown;
animation-name: rolldown;
}
HTML
<div class="overlay rolldown"></div>
thanks for any help!
You said:
...the div should be "fixed" to the top for the first 50% to scale from top to down and then it should be "fixed" at the bottom and scale down...
To solve this, I've added two steps keyframes: rolldown1 and rolldown2. First, it will animate top to down, wait 3 seconds and then animate to collapse and disappear.
Solution:
.overlay {
background: #00b2c0;
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
#keyframes rolldown1 {
0% {
-webkit-transform-origin: left top;
transform-origin: left top;
-webkit-transform: scaleY(0);
transform: scaleY(0);
}
100% {
-webkit-transform-origin: left top;
transform-origin: left top;
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
}
#keyframes rolldown2 {
0% {
-webkit-transform-origin: left bottom;
transform-origin: left bottom;
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
50% {
-webkit-transform-origin: left bottom;
transform-origin: left bottom;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
100% {
-webkit-transform-origin: left bottom;
transform-origin: left bottom;
-webkit-transform: scaleY(0);
transform: scaleY(0);
}
}
.rolldown {
/* here, it will wait for 3 seconds before collapsing */
-webkit-animation:
rolldown1 1s linear 0s 1 normal forwards,
rolldown2 1s linear 3s 1 normal forwards
;
animation:
rolldown1 1s linear 0s 1 normal forwards,
rolldown2 1s linear 3s 1 normal forwards
;
}
<div class="overlay rolldown"></div>
Your CSS has error, try the following CSS
.overlay {
background: #00b2c0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
-webkit-animation: infinite 2s;
animation: infinite 2s;
}
.off {
width: 0;
height: 0;
animation: none !important;
-webkit-animation: none !important;
}
#keyframes rolldown {
0% {
transform: scaleY(0);
transform-origin: left top;
}
50%
{
transform: scaleY(1);
}
100% {
transform: scaleY(0);
transform-origin: left bottom;
}
}
.rolldown {
-webkit-animation-name: rolldown;
animation-name: rolldown;
}
Maybe you should set height in 50% of "rolldown", try this:
.overlay {
background: #00b2c0;
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
z-index: 1;
-webkit-animation: infinite 2s;
animation: infinite 2s;
}
#keyframes rolldown {
0% {transform: scaleY(0); transform-origin: left top;}
50% { transform: scaleY(1); height: 10%; }
100% {transform: scaleY(0); transform-origin: left bottom; }
}
Try this
JSFiddle
.container{
background:#00b2c0;
height:1000px;
-webkit-animation: expand 5s;
}
#-webkit-keyframes expand{
0%{height:0px}
100%{height:1000px}
}
so, i can't got it to work with scale but I could get it working with translate!
https://jsfiddle.net/mh9j763r/1/
.overlay {
background: #00b2c0;
position: absolute;
top: -100%; left: 0;
width: 100%;
height: 100%;
z-index: 1;
-webkit-animation: infinite 2s;
animation: infinite 2s;
}
#keyframes rolldown {
0% {transform: translateY(0);}
50% { transform: translateY(100%);}
100% { transform: translateY(200%);}
}
.rolldown {
-webkit-animation-name: rolldown;
animation-name: rolldown;
}