CSS3 consistent animation speed - css

I want my leaf animate towards certain directions while slowing down its speed. I tried using ease-out to implement this effect. However, this causes my leaf to ease-out when going one direction (from 0% to 75%) and once again when going another direction (at 75% to 100%).
How do I make my leaf go directions and constantly slow down (not ease-out at every turn)?
#leaf {
height:100px;
width:100px;
animation: leaf 10s infinite ease-out;
-webkit-animation: leaf 10s infinite ease-out;
}
#keyframes leaf {
0% {
transform: translate(0, 0px) rotateZ(0deg);
}
75% {
transform: translate(200px, 300px) rotateZ(270deg);
}
100% {
transform: translate(0px, 600px) rotateZ(360deg);
}
}
#-webkit-keyframes leaf {
0% {
-webkit-transform: translate(0, 0px) rotateZ(0deg);
}
75% {
-webkit-transform: translate(200px, 300px) rotateZ(270deg);
}
100% {
-webkit-transform: translate(0px, 600px) rotateZ(360deg);
}
}

What you are using is ease-out but what you need is animation-timing-function: linear;
Demo

It can be done, but the math is not easy.
I get it just by trial and error.
You need to set a timing function for each step, and somehow adapt it to your needs.
A demo:
div {
position: absolute;
left: 10px;
top: 10px;
height:100px;
width:100px;
}
.leaf {
animation: leafa 10s infinite ease-out;
-webkit-animation: leaf 10s infinite ease-out;
animation: leaf 10s infinite ease-out;
background-color: aqua;
}
.mark {
animation: mark 10s infinite ease-out;
-webkit-animation: mark 10s infinite ease-out;
animation: mark 10s infinite ease-out;
border: solid 1px blue;
}
#-webkit-keyframes leaf {
0% { -webkit-transform: translateX(0px);
-webkit-animation-timing-function: cubic-bezier(0.4, 0.4, 0.45, 0.6);
}
35% { -webkit-transform: translateX(200px);
-webkit-animation-timing-function: cubic-bezier(0.4, 0.765, 0.6, 0.8);
}
100% { -webkit-transform: translateX(400px);
}
}
#-webkit-keyframes mark {
0% { -webkit-transform: translateX(0px); }
100% { -webkit-transform: translateX(400px); }
}
#keyframes leaf {
0% { transform: translateX(0px);
animation-timing-function: cubic-bezier(0.4, 0.4, 0.45, 0.6);
}
35% { transform: translateX(200px);
animation-timing-function: cubic-bezier(0.4, 0.765, 0.6, 0.8);
}
100% { transform: translateX(400px);
}
}
#keyframes mark {
0% { transform: translateX(0px); }
100% { transform: translateX(400px); }
}
fiddle
The mark has an standard ease out animation over the full transform. The leaf has 2 segments, and each one of them has a cubic bezier timing function.
The result is that the leaf almost matches the mark. It can be done as good as you want, it's only a matter of trying (or knowing more math that I do).
You can find this link useful.

Related

How to play multiple animations back-to-back in CSS?

I can not play several animations one after the other with a "fluid" effect:
#circle {
border-radius: 50%;
background: red;
animation: zoomIn 1s, pulse 0.5s ease 1s;
height: 100px;
width: 100px;
}
#keyframes zoomIn {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#keyframes pulse {
from {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}
<div id="circle"></div>
Am I doing something wrong? I want to keep the keyframes separate.
You may need to consider forwards on the second one to keep its last state because actually when both animations ends your element get back to the inital value of the scale transform which is scale(1) (to be more precise it's transform:none)
#circle {
border-radius: 50%;
background: red;
animation: zoomIn 1s, pulse 0.5s ease 1s forwards;
height: 100px;
width: 100px;
}
#keyframes zoomIn {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#keyframes pulse {
from {
transform: scale(1);
}
100% {
transform: scale(1.5);
}
}
<div id="circle"></div>
UPDATE
The waiting time is due to the animation-timing-function used which is ease for both and this mean that you will have an ease-out (slow at the end) and ease-in (slow at the start) which create this behavior of pausing between both animations. If you change the first one to ease-in and the last one to ease-out you won't have this issue.
#circle {
border-radius: 50%;
background: red;
animation: zoomIn 1s ease-in, pulse 0.5s ease-out 1s forwards;
height: 100px;
width: 100px;
}
#keyframes zoomIn {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#keyframes pulse {
from {
transform: scale(1);
}
100% {
transform: scale(1.5);
}
}
<div id="circle"></div>
Your pulse animation ends at scale 1.1, and then your circle snaps back to scale 1. Maybe the pulse keyframes should be as follows:
#keyframes pulse {
from {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
In the snippet below you see no snapping, but maybe this isn't the effect you were looking for?
#circle {
border-radius: 50%;
background: red;
animation: zoomIn 1s, pulse 0.5s ease 1s;
height: 100px;
width: 100px;
}
#keyframes zoomIn {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#keyframes pulse {
from {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
<div id="circle"></div>
You need a short pulse at the end when your circle is scaled to 1, this is your fluid effect I presume.
Rather than having to different animations, why don't we tweak the keyframes in the zoomIn animation a little bit.
HTML:
<div id="circle"></div>
CSS:
#circle {
border-radius: 50%;
background: red;
animation: zoomIn 0.4s ease-out;
height: 100px;
width: 100px;
}
#keyframes zoomIn {
0% {
transform: scale(0);
}
60% {
transform: scale(1);
}
80% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
Hope this helps.
the only animation is 'Transform', it is best to use a 'timing function' customization, I recommend utilities 'Cubic-bezier' go to this website http://cubic-bezier.com and practice. read before something about bezier curve.
#circle {
border-radius: 50%;
background: red;
animation: zoomIn 1s cubic-bezier(.4,.17,.49,1.54);
height: 100px;
width: 100px;
}
#keyframes zoomIn {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
<div id="circle"></div>
UPDATE
or this other 'timing-function'
#circle {
border-radius: 50%;
background: red;
animation: zoomIn 1.5s cubic-bezier(.56,1,.92,.7);
height: 100px;
width: 100px;
animation-fill-mode: forwards; /* */
}
#keyframes zoomIn {
0% {
transform: scale(0);
}
100% {
transform: scale(1.1);
}
}
<div id="circle"></div>

Multiple CSS animation effects in parallel

To terrify the guys at Pixar (with my animation skills), I am attempting to get a walking effect to work using CSS ...
Unfortunately, I am unable to work two different animation effects in parallel, I want the steps to rotate at a variable rate to the walkRight transition.
Here is my current attempt:
CSS
.wrapper {
position: absolute;
width: 100px;
height: 100px;
right: 0;
animation-name: walkRight;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 10s;
}
.hulk {
-webkit-animation: steps 10s linear 0s;
}
#keyframes walkRight {
0% {
transform: translateX(-400px);
}
100% {
transform: translateX(0);
}
}
#-webkit-keyframes steps {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(20deg);
}
50% {
-webkit-transform: rotate(0deg);
}
75% {
-webkit-transform: rotate(-20deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
Here is an example JsFiddle
You could try to:
Use animation-iteration-count: 10 on hulk class and set is duration to 1s (as walkRight has 10s duration), this means the walk effect will be applied 10 times during the walk.
Prefix all properties using -webkit- to make sure browsers will render your animation properly, you could use autoprefixer (or similar) which does the job for you automatically.
.wrapper {
position: absolute;
width: 100px;
height: 100px;
right: 0;
-webkit-animation-name: walkRight;
animation-name: walkRight;
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
-webkit-animation-duration: 10s;
animation-duration: 10s;
}
.hulk {
-webkit-animation: steps 1s linear 0s;
-webkit-animation-iteration-count: 10;
animation-iteration-count: 10;
}
#-webkit-keyframes walkRight {
0% {
-webkit-transform: translateX(-400px);
transform: translateX(-400px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#keyframes walkRight {
0% {
-webkit-transform: translateX(-400px);
transform: translateX(-400px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#-webkit-keyframes steps {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(20deg);
}
50% {
-webkit-transform: rotate(0deg);
}
75% {
-webkit-transform: rotate(-20deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
<div class="wrapper">
<img class="hulk" width="100px" src="http://vignette3.wikia.nocookie.net/heroup/images/4/4b/Thing_full_body.png/revision/latest?cb=20120117152657">
</div>
You can use animation-iteration-count on steps animation and set shorter duration. You just need to match ending time for both walk and steps that will repeat itself n number of times, so in this case its about 9 if duration is 1s.
.wrapper {
position: absolute;
width: 100px;
height: 100px;
right: 0;
animation-name: walkRight;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 10s;
}
.hulk {
-webkit-animation: steps 1s linear 0s;
animation-iteration-count: 9;
}
#keyframes walkRight {
0% {
transform: translateX(-400px);
}
100% {
transform: translateX(0);
}
}
#-webkit-keyframes steps {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(20deg);
}
50% {
-webkit-transform: rotate(0deg);
}
75% {
-webkit-transform: rotate(-20deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
<div class="wrapper">
<img class="hulk" width="100px" src="http://vignette3.wikia.nocookie.net/heroup/images/4/4b/Thing_full_body.png/revision/latest?cb=20120117152657">
</div>

CSS3 animations work on click

I'm attempting to make a welcome page that, once you click on it, will fall by a CSS transition.
I can't figure out how to make the page fall, I can only make the button fall when the page loads.
here's what I have:
<style>
pt-page-rotateFall {
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
-webkit-animation: rotateFall 1s both ease-in;
animation: rotateFall 1s both ease-in;}
a {
color:black;
text-align:center;
-moz-transition:all 1s ease; -webkit-transition:all 1s ease; transition:all 1s ease;
-o-transition:all 1s ease; -ms-transition:all 1s ease;
}
a:focus {
0% { -webkit-transform: rotateZ(0deg); }
20% { -webkit-transform: rotateZ(10deg); -webkit-animation-timing-function: ease-out; }
40% { -webkit-transform: rotateZ(17deg); }
60% { -webkit-transform: rotateZ(16deg); }
100% { -webkit-transform: translateY(100%) rotateZ(17deg); }
0% { -webkit-transform: rotateZ(0deg); transform: rotateZ(0deg); }
20% { -webkit-transform: rotateZ(10deg); transform: rotateZ(10deg); -webkit-animation-timing-function: ease-out; animation-timing-function: ease-out; }
40% { -webkit-transform: rotateZ(17deg); transform: rotateZ(17deg); }
60% { -webkit-transform: rotateZ(16deg); transform: rotateZ(16deg); }
100% { -webkit-transform: translateY(100%) rotateZ(17deg); transform: translateY(100%) rotateZ(17deg); }
}
Welcome
You will need Javascript to do that. You could either handle the animation itself in Javascript completely, or add a click event listener and give the element the class pt-pate-rotateFall within the handler.

How to move image in the circular motion by having start and end degree as same using css3?

.ball{
position:absolute;
top: 200px;
left: 300px;
height:100px;
width:100px;
background-color: yellow;
border-radius: 100px;
-webkit-animation: balls 4s linear;
animation: balls 4s linear;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
#-webkit-keyframes balls {
0% { transform: rotate(0deg) translateX(150px) rotate(0deg); }
100% { transform: rotate(0deg) translateX(150px) rotate(360deg); }
}
#keyframes balls {
from { transform: rotate(0deg) translateX(150px) rotate(0deg); }
to { transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
The above was my code to rotate in the circuar motion. I want my start and end degree as same and also it should rotate in the circular motion. Please help me with the solution to my problem
I would use this code to rotate a image (it never stops):
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
-webkit-animation:spin 4s linear infinite;
-moz-animation:spin 4s linear infinite;
animation:spin 4s linear infinite;
}
#-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
#-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
#keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
If you just want 360 degrees, delete the word infinite and it should work.
EDIT: Here a Demo
Have found solution for my problem.
By having 'from' degree we can calculate the 'to' degree as 'from+359' so it will rotate a whole round by having the single degree

Bugs with chaining CSS3 animations

I'm trying to chain CSS3 animations together, but they behave very weird sometimes. For example, in this pen, why won't the last animation start? I got it working before, but it doesn't anymore, and I used the same setup. The code I'm pasting here is a little bit simplified, but the animations are exactly the same:
HTML:
<div class="box"></div>
CSS:
body {
padding: 60px;
}
.box {
width: 100px;
height: 100px;
background-color: black;
animation-name: fadeIn, fall, elastic;
animation-timing-function: ease, ease-in, ease-out;
animation-duration: 1s, 0.5s, 0.5s;
animation-delay: 0s, 0s, 0.5s;
animation-fill-mode: forwards, forwards, forwards;
}
#keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
#keyframes fall {
0% { transform: translateY(-100px); }
100% { transform: translateY(0px); }
}
#keyframes elastic {
0% { transform: translateY(0px); }
20% { transform: translateY(60px); }
40% { transform: translateY(-20px); }
60% { transform: translateY(10px); }
80% { transform: translateY(-5px); }
100% { transform: translateY(0px); }
}
Maybe I'm wrong... but it seems that this does not "chain" them since they play simultaneously. If that's the case, then the last one probably isn't working because you're already keyframeing translateY in the second animation.

Resources