I'm looking at optimising CSS animations for performance.
From what I can find out using
.item { transform: translate(-25px,-50px)
is much more efficient than
.item { left: -25px; top: -50px }
I've setup a little animation that move and rotates a box .balloon which as multiple steps to the animation. The problem is though the animation becomes very jerky, even with positioning ans rotation declared for each step
Here is my standard CSS
#keyframes balloon {
0%,100% { left:809px; top:50px; transform: rotate(0deg) }
10% { transform: rotate(-9deg) }
25%,75% { top:25px }
50% { left:235px;top:75px }
45% { transform: rotate(3deg) }
75% { transform: rotate(12deg) }
}
This is my optimised CSS, which is where the jerky animation comes in to effect
#keyframes balloon {
0% { transform: translate(0,0) rotate(0deg) }
10% { transform: translate(-57.5px,-10px) rotate(-9deg) }
25% { transform: translate(-143.75px,-25px) rotate(-4deg) }
45% { transform: translate(-517.5px,22.5px) rotate(3deg) }
50% { transform: translate(-575px,25px) rotate(4.5deg) }
75% { transform: translate(-287.5px,-25px) rotate(12deg) }
100% { transform: translate(0,0) rotate(0deg) }
}
Is there an alternative solution for this?
I've put a CodePen together here.
In your animation-property, try to add a value for the animation-timing-function
Something like
animation: balloon 15s infinite linear;
would make it more smooth.
Related
I am trying to make an Oscillatory animation using css as shown below:
Here's how I have created my animation:
#keyframes rotateFeather {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(-180deg);
}
50% {
transform: rotate(-90deg);
}
75% {
transform: rotate(90deg);
}
100% {
transform: rotate(180deg);
}
}
Here is my class: (Using sccs)
.logo {
height: 5rem;
transition: all 0.3s ease;
&box {
position: absolute;
top: 4rem;
left: 4rem;
}
&:hover {
animation-name: rotateFeather;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
}
Here I am facing this problem: When it reaches 180deg at 100% it abruptly resets to 0 which I want to make smooth.
How is it possible to do the same?
To ensure smooth transition, We need to make sure that transformation at 0 and 100% must match with the original state:
#keyframes rotateFeather {
0% {
transform: rotate(0deg); //-30
transform-origin: bottom;
}
20% {
transform: rotate(-30deg); //-60
transform-origin: bottom;
}
40% {
transform: rotate(0deg); //-30
transform-origin: bottom;
}
60% {
transform: rotate(30deg); // 0
transform-origin: bottom;
}
80% {
transform: rotate(60deg); //30
transform-origin: bottom;
}
100% {
transform: rotate(0deg); //30
transform-origin: bottom;
}
}
This helped me to solve my issue. I am not sure, if I need to add transform-origin in every stage, if someone can elaborate better on that, that would be helpful.
Here's a simplified version of your latest animation code (with a Codepen to see it in action):
#keyframes rotateFeather {
0% {
transform: rotate(0deg);
}
20% {
transform: rotate(-30deg);
}
80% {
transform: rotate(60deg);
}
100% {
transform: rotate(0deg);
}
}
.logo {
transform-origin: bottom;
&:hover {
animation: rotateFeather 1s linear infinite;
}
}
Some points about the above tweaks:
You don't need transform-origin at every keyframe. You can set it globally.
You can roll all of your animation properties into a single shorthand rule.
You can skip keyframes that are mathematically interpolating where the animation would be going anyway (notice I omitted 40% and 60% above and it looks the same).
You don't need any transition rules on elements that you are animating with keyframes. Unless you're using it for something else, but you want to be careful to avoid attempting to animate the same property on the same element with both animation and transition simultaneously, as it will break the animation in question.
I'm trying to make a css rotation animation that has different speeds at different degree points.
Here is the animation I'm trying to make:
Here is a Pen of what I currently have and below is the code:
img {
width: 125px;
}
body {
text-align: center;
}
#loading {
-webkit-animation: slow 1.5s linear 1.5s, fast 1s linear 1s, slow2 1s linear 1s;
-webkit-animation-iteration-count: infinite;
}
#-webkit-keyframes slow {
from {
-webkit-transform: rotate(0deg)
}
to {
-webkit-transform: rotate(90deg)
}
}
#-webkit-keyframes fast {
from {
-webkit-transform: rotate(91deg)
}
to {
-webkit-transform: rotate(270deg)
}
}
#-webkit-keyframes slow2 {
from {
-webkit-transform: rotate(271deg)
}
to {
-webkit-transform: rotate(359deg)
}
}
<img id="loading" src="https://i.imgur.com/VpLRlbZ.png">
So, in the example you provided, the effect is only done by modifying the animation-timing-function css property.
Then you'll have only one animation
div {
width:100px;
height:100px;
background:red;
animation:rotate 3s infinite;
animation-timing-function: cubic-bezier(1,0,.5,1);
}
#-webkit-keyframes rotate {
from { -webkit-transform: rotate(0deg) }
to { -webkit-transform: rotate(360deg) }
}
<div></div>
You can find more informations here : https://callmenick.com/dev/level-up-animations-cubic-bezier/
But the point is, use only one animation and modify speed at different angles value modifying this animation-timing-function.
EDIT Added a closer cubic bezier timing function thanks to #SirExotic comment.
You can just divide the animation keyframes into several ones, and adjust the percentages of each to set the relative speeds:
The natural percentage for 90deg would be 25% . Any value higher than that will make this part slower
img {
width: 125px;
}
body {
text-align: center;
}
#loading {
animation: rotate 4s linear infinite;
}
#keyframes rotate {
0% {
transform: rotate(0deg)
}
40% {
transform: rotate(90deg)
}
60% {
transform: rotate(270deg)
}
100% {
transform: rotate(360deg)
}
}
<img id="loading" src="https://i.imgur.com/VpLRlbZ.png">
I'm trying to make a ship moves from left to right and from top to bottom at the same time (it describes a straight downward line). I want to assign different speeds to the animation in the 'X' and 'Y' axis. I mean I want little ship to move slower when moving from left to right, and faster when moving from top to bottom, but I haven't been able to accomplish this because I don't know how to separate the speed of the different animated properties. I would highly appreciate any suggestion. Here is my code:
body {
overflow-x:hidden;
}
div {
width: 150px;
height: 150px;
top: 20px;
background-image: url('https://s-media-cache-ak0.pinimg.com/originals/c2/bb/ae/c2bbaed0207deef5775af9c01e1b31ba.jpg');
position: relative;
background-size: cover;
animation: mymove 5s linear infinite;
}
#-webkit-keyframes mymove {
0% {
left:-1%;
top:-1%;
transform: rotate(5deg)
}
20% {
transform: rotate(-5deg)
}
40%
{
transform: rotate(5deg)
}
60% {
transform: rotate(-5deg)
}
80%{
transform: rotate(5deg)
}
100% {
left:100%;
top:100%;
transform: rotate(-5deg)
}
}
<div></div>
Thanks in advance!
Try this updated keyframe
#-webkit-keyframes mymove {
0% {
left:-1%;
transform: rotate(5deg)
}
20% {
transform: rotate(-5deg)
}
40%
{
left:90%;
transform: rotate(5deg)
}
60% {
transform: rotate(90deg) translate(0px,0px)
}
80%{
transform: rotate(95deg) translate(210px,0px)
}
100% {
left:90%;
transform: rotate(90deg) translate(410px,0px)
}
}
Updated answer#1
ship will travel diagonally
#-webkit-keyframes mymove {
0% {
transform: translate(0px,0px) rotate(55deg)
}
10% {
transform: translate(100px,50px) rotate(60deg)
}
20% {
transform: translate(200px,100px) rotate(55deg)
}
30% {
transform: translate(300px,150px) rotate(60deg)
}
40% {
transform: translate(400px,200px) rotate(55deg)
}
50% {
transform: translate(500px,250px) rotate(60deg)
}
60% {
transform: translate(600px,300px) rotate(55deg)
}
70% {
transform: translate(700px,350px) rotate(60deg)
}
80% {
transform: translate(800px,400px) rotate(55deg)
}
90% {
transform: translate(900px,450px) rotate(60deg)
}
100% {
transform: translate(1000px,500px) rotate(55deg)
}
}
I'm trying to create a simple animation, an element should do a full spin around a radius(using transform-origin), the problem is that I want that element to begin with an angle.
For a spin that starts from 0deg, I know I can do:
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
But I want it to start with an angle, and this doesn't work:
#keyframes spin {
0% { transform: rotate(45deg); }
100% { transform: rotate(45deg); }
}
I understand why. because its the same point... but how do i do a full spin in this case?
Here's a simplified version of it. I have no problem with mixing this with JS to make it work:
https://jsfiddle.net/shock/qqdkj7hx/
Try the following:
#keyframes spin {
0% { transform: rotate(45deg); }
100% { transform: rotate(405deg); }
}
FIDDLE
Here's the demo: http://codepen.io/anon/pen/WGLGyY
the DIV doesn't rotate when the keyframe is:
#keyframes test1{
0% {
transform: rotate(0) scale(1, 1) translate(0,0)
}
100% {
transform: scale(2, 2) rotate(180deg) translate(200px,200px)
}
}
when I change the keyframe to:
#keyframes test1{
0% {
transform: rotate(0) scale(1, 1) translate(0,0)
}
100% {
transform: rotate(360deg) scale(2, 2) translate(200px,200px)
}
}
It rotate again.
So what's the reason here?
I know the order may affect the transform.
Maybe because rotate(360deg) equals rotate(0); But when I change the order of transform it comes back again....
Use transform: none for your first keyframe, and it will rotate.
Here it is in action:
#keyframes test1{
0% {
transform: none;
}
100% {
transform: scale(2, 2) rotate(360deg) translate(200px,200px)
}
}
#test{
width:200px;
height: 200px;
background: red;
animation: test1 3s infinite
}
<div id="test"></div>