I'm wondering if it would be possible to achieve an "accelerate, then coast" animation with css, like in this 3D.js example
Basically, an object starts with 0 speed and accelerated its movement until a certain point, and after that, it keeps a constant speed.
I thought it could be accomplished by applying the rotation animation twice to the same element, but with different parameters:
* first rotation: the object rotates during 2 seconds, with no delay, with an ease-in function;
* after that: the object rotates during 1.5 seconds with a 2 seconds delay to account for the first rotation, with a linear function. This time the rotation repeats infinitely.
So I tried the following code
.square {
width: 120px;
height: 120px;
background: #c00;
-webkit-animation:
spin 2s 0 ease-in 1,
spin 1.5s 2s linear infinite;
-moz-animation:
spin 2s 0 ease-in 1,
spin 1.5s 2s linear infinite;
animation:
spin 2s 0 ease-in 1,
spin 1.5s 2s linear infinite;
}
}
#-moz-keyframes spin {
100% { -moz-transform: rotate(360deg); }
}
#-webkit-keyframes spin {
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
100% { transform:rotate(360deg); }
}
I know it's not the same as the 3D.js example, but it's close enough. The problem is that the object stops a bit before finishing the first rotation and it looks really weird.
I've prepared a fiddle to show the problem: http://jsfiddle.net/e0sLc8sw/
Any idea?
Thanks everybody for your help!
is it not just because you have added 2 times to the second animation?
According to MDN, the second time entry is treated as an animation-delay, which tells the animation to start after that period of time.
Removing the 2s part from the animation works fine:
.square {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
width: 100px;
height: 100px;
background: #c00;
-webkit-animation:
spin 2s 0 ease-in 1,
spin 1.5s linear infinite;
-moz-animation:
spin 2s 0 ease-in 1,
spin 1.5s linear infinite;
animation:
spin 2s 0 ease-in 1,
spin 1.5s linear infinite;
}
#-moz-keyframes spin {
100% { -moz-transform: rotate(360deg); }
}
#-webkit-keyframes spin {
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
100% { transform:rotate(360deg); }
}
<div class="square spinning">:D</div>
UPDATED FIDDLE
The previous examples don't work in modern Chrome (2018). Here's an updated example using a cubic bezier curve to handle the acceleration - you can play around with the acceleration parameters here.
The first animation handles the acceleration - the 3s here indicates it will get to the last frame after 3 seconds with the bezier acceleration function. It then terminates. The 3s in the second animation indicates this one begins exactly where the other one left off, ie it has a 3 second delay, but this one never terminates as it has "infinite" duration. It's much faster at 0.5 seconds.
Ideally the 0.5 second speed should be matched to the precise speed of the first animation caused by the Bezier acceleration. This is a manual calculation I don't think CSS helps with and I didn't perform here, just used an eye test.
.square {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
width: 100px;
height: 100px;
background: #c00;
animation:
spin 3s cubic-bezier(.52,.29,.83,.13),
spin 0.5s linear 3s infinite;
}
#keyframes spin {
100% { transform:rotate(360deg); }
}
<div class="square spinning">:D</div>
Related
This is simple rotation keyframe animation on hover. Works fine starts fine, but when pointer is moved out animation suddenly stops and cube jumps back to initial state. Is it possible with just css to add easing time or anything to smoothen the stopping when pointer is moved out.
#keyframes rotating {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#cube:hover {
animation: rotating 12s linear infinite;
}
#cube{
width: 100px;
height: 100px;
background:red;
transition-duration: 3s; /*Doesn't work*/
}
#cubeb {
width: 100px;
height: 100px;
background:red;
transition: transform 12s linear;
}
#cubeb:hover {
transform: rotate(360deg);
}
<div id="cube">Jump When hover ends</div>
<br/>
<div id="cubeb">No Jump but does not continuously rotate on hover</div>
You can try animation-play-state
#keyframes rotating {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#cube:hover {
animation-play-state: running;
}
#cube {
width: 100px;
height: 100px;
background: red;
animation: rotating 12s linear infinite paused;
}
<div id="cube">Jump When hover ends</div>
you can add an easing effect to the rotation animation so that it smoothens the transition when the pointer is moved out.
You can the ease-in-out timing function, which gradually speeds up and then slows down the rotation:
#cube:hover {
animation: rotating 12s ease-in-out infinite;
}
You can also adjust the duration of the easing effect:
#cube:hover {
animation: rotating 12s cubic-bezier(0.25, 0.1, 0.25, 1.0) infinite;
}
How can I have two CSS animations playing at different speeds?
The image should be rotating and growing at the same time.
The rotation will cycle every 2 seconds.
The growth will cycle every 4 seconds.
Example Code:
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;
}
#-webkit-keyframes spin {
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes scale {
100% {
transform: scaleX(2) scaleY(2);
}
}
http://jsfiddle.net/Ugc5g/3388/ - only one animation (the last one declared) plays.
You can specify multiple animations--each with their own properties--with a comma.
Example:
animation: rotate 1s, spin 3s;
TL;DR
With a comma, you can specify multiple animations each with their own properties as stated in the CriticalError answer below.
Example:
animation: rotate 1s, spin 3s;
Original answer
There are two issues here:
#1
-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;
The second line replaces the first one. So, has no effect.
#2
Both keyframes applies on the same property transform
As an alternative you could to wrap the image in a <div> and animate each one separately and at different speeds.
http://jsfiddle.net/rnrlabs/x9cu53hp/
.scaler {
position: absolute;
top: 100%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
animation: scale 4s infinite linear;
}
.spinner {
position: relative;
top: 150px;
animation: spin 2s infinite linear;
}
#keyframes spin {
100% {
transform: rotate(180deg);
}
}
#keyframes scale {
100% {
transform: scaleX(2) scaleY(2);
}
}
<div class="spinner">
<img class="scaler" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">
<div>
You can indeed run multiple animations simultaneously, but your example has two problems. First, the syntax you use only specifies one animation. The second style rule hides the first. You can specify two animations using syntax like this:
-webkit-animation-name: spin, scale
-webkit-animation-duration: 2s, 4s
as in this fiddle (where I replaced "scale" with "fade" due to the other problem explained below... Bear with me.): http://jsfiddle.net/rwaldin/fwk5bqt6/
Second, both of your animations alter the same CSS property (transform) of the same DOM element. I don't believe you can do that. You can specify two animations on different elements, the image and a container element perhaps. Just apply one of the animations to the container, as in this fiddle: http://jsfiddle.net/rwaldin/fwk5bqt6/2/
You cannot play two animations since the attribute can be defined only once. Rather why don't you include the second animation in the first and adjust the keyframes to get the timing right?
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
-webkit-animation:spin-scale 4s linear infinite;
}
#-webkit-keyframes spin-scale {
50%{
transform: rotate(360deg) scale(2);
}
100% {
transform: rotate(720deg) scale(1);
}
}
<img class="image" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">
you can try something like this
set the parent to rotate and the image to scale so that the rotate and scale time can be different
div {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin: -60px 0 0 -60px;
-webkit-animation: spin 2s linear infinite;
}
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin: -60px 0 0 -60px;
-webkit-animation: scale 4s linear infinite;
}
#-webkit-keyframes spin {
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes scale {
100% {
transform: scale(2);
}
}
<div>
<img class="image" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120" />
</div>
Turn these 2 lines:
-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;
into:
-webkit-animation: spin 2s linear infinite, scale 4s linear infinite;
I am using WOW.js and animate.css, right now I am running my CSS to Infinite. I would like know how can I make my class run for 3 seconds stop and start again to infinite?
My html:
<img src="images/fork.png" class="fork wow rubberBand" >
My CSS class:
.fork {
position: absolute;
top: 38%;
left: 81%;
max-width: 110px;
-webkit-animation-iteration-count: infinite ;
-webkit-animation-delay: 5s;
}
The solution can be in JS or CSS3.
With pure CSS3 animations, one way to add a delay between every single iteration of the animation would be to modify the keyframes setting such that they produce the required delay.
In the below snippet, the following is what is being done:
The whole duration of the animation is 6 seconds. In order to have the delay, the whole duration should be the duration for which your animation actually runs + time delay. Here, the animation actually runs for 3s, we need a 3s delay and so the duration is set as 6 seconds.
For the first 50% of the animation (that is, 3 seconds), nothing happens and the element basically holds its position. This gives the appearance of the 3 second delay being applied
For the next 25% of the animation (that is, 1.5 seconds) the element moves down by 50px using transform: translateY(50px).
For the final 25% of the animation (that is, last 1.5 seconds) the element moves up by 50px using transform: translate(0px) (back to its original position).
The whole animation is repeated infinite number of times and each iteration will end up having a 3 second delay.
div{
height: 100px;
width: 100px;
border: 1px solid;
animation: move 6s infinite forwards;
}
#keyframes move{
0% { transform: translateY(0px);}
50% { transform: translateY(0px);}
75% { transform: translateY(50px);}
100% { transform: translateY(0px);}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>Some content</div>
The animation-delay property introduces a delay only for the first iteration and hence it cannot be used to add delays between every iteration. Below is a sample snippet illustrating this.
div{
height: 100px;
width: 100px;
border: 1px solid;
animation: move 6s infinite forwards;
animation-delay: 3s;
}
#keyframes move{
0% { transform: translateY(0px);}
50% { transform: translateY(50px);}
100% { transform: translateY(0px);}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>Some content</div>
LIke this
html
<div class="halo halo-robford-animate"></div>
css
body{
background: black;
}
.halo{
width: 263px;
height: 77px;
background: url('http://i.imgur.com/3M05lmj.png');
}
.halo-robford-animate{
animation: leaves 0.3s ease-in-out 3s infinite alternate;
-webkit-animation: leaves 0.3s ease-in-out 3s infinite alternate;
-moz-animation: leaves 0.3s ease-in-out 3s infinite alternate;
-o-animation: leaves 0.3s ease-in-out 3s infinite alternate;
}
#-webkit-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#-moz-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#-o-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5
}
100% {
opacity: 1;
}
}
jsfiddle
How can I have two CSS animations playing at different speeds?
The image should be rotating and growing at the same time.
The rotation will cycle every 2 seconds.
The growth will cycle every 4 seconds.
Example Code:
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;
}
#-webkit-keyframes spin {
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes scale {
100% {
transform: scaleX(2) scaleY(2);
}
}
http://jsfiddle.net/Ugc5g/3388/ - only one animation (the last one declared) plays.
You can specify multiple animations--each with their own properties--with a comma.
Example:
animation: rotate 1s, spin 3s;
TL;DR
With a comma, you can specify multiple animations each with their own properties as stated in the CriticalError answer below.
Example:
animation: rotate 1s, spin 3s;
Original answer
There are two issues here:
#1
-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;
The second line replaces the first one. So, has no effect.
#2
Both keyframes applies on the same property transform
As an alternative you could to wrap the image in a <div> and animate each one separately and at different speeds.
http://jsfiddle.net/rnrlabs/x9cu53hp/
.scaler {
position: absolute;
top: 100%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
animation: scale 4s infinite linear;
}
.spinner {
position: relative;
top: 150px;
animation: spin 2s infinite linear;
}
#keyframes spin {
100% {
transform: rotate(180deg);
}
}
#keyframes scale {
100% {
transform: scaleX(2) scaleY(2);
}
}
<div class="spinner">
<img class="scaler" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">
<div>
You can indeed run multiple animations simultaneously, but your example has two problems. First, the syntax you use only specifies one animation. The second style rule hides the first. You can specify two animations using syntax like this:
-webkit-animation-name: spin, scale
-webkit-animation-duration: 2s, 4s
as in this fiddle (where I replaced "scale" with "fade" due to the other problem explained below... Bear with me.): http://jsfiddle.net/rwaldin/fwk5bqt6/
Second, both of your animations alter the same CSS property (transform) of the same DOM element. I don't believe you can do that. You can specify two animations on different elements, the image and a container element perhaps. Just apply one of the animations to the container, as in this fiddle: http://jsfiddle.net/rwaldin/fwk5bqt6/2/
You cannot play two animations since the attribute can be defined only once. Rather why don't you include the second animation in the first and adjust the keyframes to get the timing right?
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
-webkit-animation:spin-scale 4s linear infinite;
}
#-webkit-keyframes spin-scale {
50%{
transform: rotate(360deg) scale(2);
}
100% {
transform: rotate(720deg) scale(1);
}
}
<img class="image" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">
you can try something like this
set the parent to rotate and the image to scale so that the rotate and scale time can be different
div {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin: -60px 0 0 -60px;
-webkit-animation: spin 2s linear infinite;
}
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin: -60px 0 0 -60px;
-webkit-animation: scale 4s linear infinite;
}
#-webkit-keyframes spin {
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes scale {
100% {
transform: scale(2);
}
}
<div>
<img class="image" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120" />
</div>
Turn these 2 lines:
-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;
into:
-webkit-animation: spin 2s linear infinite, scale 4s linear infinite;
.bg-grass{
width: 100%;
height: 290px;
background-size: :100%;
background-image: url(../graphic/background/001.png);
background-position: 0px 0px;
background-repeat: repeat-x;
animation: animatedBackground 20s linear infinite;
-ms-animation: animatedBackground 20s linear infinite;
-moz-animation: animatedBackground 20s linear infinite;
-webkit-animation: animatedBackground 20s linear infinite;
}
.grass-speed2{
animation: animatedBackground 5s linear infinite;
-ms-animation: animatedBackground 5s linear infinite;
-moz-animation: animatedBackground 5s linear infinite;
-webkit-animation: animatedBackground 5s linear infinite ;
}
I have two css classes which one is to have a normal animation and another to make it faster. The scenario would be that at certain time, the grass-speed2 class would be added into bg-grass to make the speed faster. It works fine in firefox but its not working in chrome. Am not sure why. Also is there a way to make it continue which background position it is currently at when the speed is being increased?
EDIT 1
I have forgotten to add in the keyframe css
#keyframes animatedBackground {
from { background-position: 0 0; }
to { background-position: 100% 0; }
}
This might be better handled through the use of animation key-frames. Instead of using different classes, try perhaps using different percentages in the key-frames combined with seconds. Here is an example using top. Of course, you can replace this (or add more) with the more appropriate animation type.
#keyframes animatedTop {
0% {
top: 0;
}
90% {
top: 5px;
}
100% {
top: 8px;
}
}
Remember to include the prefixes.
/* #-webkit-
#-moz-
#-o-
*/
And you can call your animation by using.
.myClass {
animation: animatedTop 15s;
}
Please upload your code some where and make a demo so that we can figure-out the real problem.
Just a quick note, remember to add browser vender prefix before keyframe css as well:
#-webkit-keyframes animatedBackground{...}
#-moz-keyframes animateBackground{...}
#-o-keyframes animateBackground{....}
Probably this may solve your problem.
Enjoy css keyframe animation!