Is it possible to have multiple independent transform animations? - html

I want to run two separate keyframe transform animations on the same element but it only seems to run the last animation. Is there a way to do this?
I have tried the example in the code below (codepen), as well, I've tried using position absolute on the element and animating the top and left values. It gives the effect I'm looking for, but it doesn't seem as smooth as using translate.
#keyframes animate-x {
from { transform: translateX(0); } to { transform: translateX(100%); }
}
#keyframes animate-y {
from { transform: translateY(0); } to { transform: translateY(100%); }
}
.element {
width: 200px;
height: 200px;
background-color: blue;
transform-origin: center;
animation:
animate-x 20s linear infinite alternate,
animate-y 15s linear infinite alternate;
}
I'm looking to run both the translateX and translateY animations simultaneously at different speeds.

No, but you can combine multiple transform directives into one property:
#keyframes animate-y {
from {
transform: translateY(0) translateX(0);
}
to {
transform: translateY(100%) translateX(100%);
}
}
.element {
width: 200px;
height: 200px;
background-color: blue;
transform-origin: center;
animation:
/*animate-x 2s linear infinite alternate,*/
animate-y 2s linear infinite alternate;
}
<div class="element"></div>
Also, you can break up the animation by using percentages in your keyframes instead of from and to:
#keyframes animate-y {
0% {
transform: translateY(0);
}
25% {
transform: translateY(100%) translateX(0);
}
50%{
transform: translateY(100%) translateX(100%);
}
75% {
transform: translateY(0%) translateX(100%);
}
}
.element {
width: 200px;
height: 200px;
background-color: blue;
transform-origin: center;
animation:
/*animate-x 2s linear infinite alternate,*/
animate-y 2s linear infinite alternate;
}
<div class="element"></div>
Edit: Move two directions at different speeds:
#keyframes animate-y {
0% {
transform: translateY(0) translateX(0%);
}
25% {
transform: translateY(100%) translateX(50%);
}
50%{
transform: translateY(0%) translateX(100%);
}
75% {
transform: translateY(100%) translateX(50%);
}
}
.element {
width: 200px;
height: 200px;
background-color: blue;
transform-origin: center;
animation:
/*animate-x 2s linear infinite alternate,*/
animate-y 2s linear infinite alternate;
}
<div class="element"></div>

Related

circular animation using CSS

I'm trying to create an animation for a three-letter word. For now, take the word XYZ. The idea is that each letter of XYZ will move in a circular path of different radii and directions (Like one letter moving right, another left, and bottom) before coming back to the original position. I have tried using different forms of code for this but am failing because I don't clearly understand how to animate circular motion with a fixed origin. Will be helpful if anyone could share how to do this. I am also attaching part of my code
.animation-container {
display: flex;
position: relative;
top: 10rem;
left: 50%;
align-items: center;
text-align: center;
}
.letter {
animation: move-letter 4s ease-in-out infinite;
animation-iteration-count: infinite;
}
#keyframes move-letter {
from {
-webkit-transform: rotate(0deg) translateX(150px) rotate(0deg);
}
to {
-webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg);
}
}
<div class="animation-container">
<div class="letter X">X</div>
<div class="letter Y">Y</div>
<div class="letter Z">Z</div>
</div>
It depends what you actually want, but you definitely need three different animations (i.e. with different settings), and 3 or more stages per animation, returning to the first position in each case:
.animation-container {
display: flex;
position: relative;
top: 10rem;
left: 50%;
align-items: center;
text-align: center;
}
.letter.X {
animation: move-letter_x 4s ease-in-out infinite;
animation-iteration-count: infinite;
}
.letter.Y {
animation: move-letter_y 4s ease-in-out infinite;
animation-iteration-count: infinite;
}
.letter.Z {
animation: move-letter_z 4s ease-in-out infinite;
animation-iteration-count: infinite;
}
#keyframes move-letter_x {
0% {
-webkit-transform: rotate(0deg) translateX(150px) rotate(0deg);
}
50% {
-webkit-transform: rotate(360deg) translateX(20px) rotate(-360deg);
}
100% {
-webkit-transform: rotate(0deg) translateX(150px) rotate(0deg);
}
}
#keyframes move-letter_y {
0% {
-webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg);
}
50% {
-webkit-transform: rotate(0deg) translateX(80px) rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg);
}
}
#keyframes move-letter_z {
0% {
-webkit-transform: rotate(0deg) translateX(150px) rotate(0deg);
}
50% {
-webkit-transform: rotate(360deg) translateX(140px) rotate(-360deg);
}
100% {
-webkit-transform: rotate(0deg) translateX(150px) rotate(0deg);
}
}
<div class="animation-container">
<div class="letter X">X</div>
<div class="letter Y">Y</div>
<div class="letter Z">Z</div>
</div>

I have gone through many posts saying "to add multiple animations, we can add them just by using commas(,)" but, in my case, its not happening

#box{
animation:moving-box 20s linear infinite, box-rotation 20s linear infinite;
transform-origin: center;
}
#keyframes box-rotation{
from{
transform: rotateZ(0deg);
}
to{
transform: rotateZ(360deg);
}
}
#keyframes moving-box {
0%{
transform: translateX(-40%);
}
50%{
transform: translateX(40%);
}
100%{
transform: translateX(-40%);
}
}
You have to combine the transforms otherwise the transform set in one set of keyframes will overwrite the transforms set in another.
In your example it is possible to combine the two transforms and use them in one set of keyframes:
#box {
animation: moving-box 20s linear infinite;
transform-origin: center;
width: 20vmin;
height: 10vmin;
background-color: red;
}
#keyframes moving-box {
0% {
transform: rotateZ(0deg) translateX(-40%);
}
50% {
transform: rotateZ(180deg) translateX(40%);
}
100% {
transform: rotateZ(360deg) translateX(-40%);
}
}
<div id="box"></div>
Such a solution would have to be carefully worked through for a more complex case - for example different timings or different easing functions.

css animation not rotating the box

** why box not rotating but its translating the box . translateX is working but rotate is not working in animation **
<style>
.box{
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate{
0%{
transform: translateX(100px);
}
100%{
transform: rotate(360deg);
}
}
</style>
<div class="box">
</div>
You need to add both the transform properties in the keyframe, take a look at the snippet below
.box{
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate{
0%{
transform: translateX(100px) rotate(0deg);
}
100%{
transform: translateX(0) rotate(360deg);
}
}
<div class="box">
</div>
This is because it cannot rotate 360deg at the end of the animation.
Almost anything below 360deg will work. Please provide an illustration or video of the result you are trying to accomplish if this solution is not exactly what you want.
<style>
.box {
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate {
0% {
transform: translateX(100px);
}
100% {
transform: rotate(180deg);
}
}
</style>
<div class="box"></div>
However if you only want it to spin 360deg and not translateX, you can do it using:
<style>
.box {
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<div class="box"></div>

CSS3 Animation pendulum effect

I want pendulum effect with pure CSS but it's not smooth.
Here is what I want, but with pure CSS. http://www.webdevdoor.com/demos/html5-pendulum-demo/
But I prefer more looked like natural speed variation according to it's position.
Fiddle
.bellImg {
height: 20px;
width: 20px;
position: absolute;
right: 10px;
top: 18px;
-webkit-animation-name: rotate;
animation-delay: 3s;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: linear;
-webkit-transform-origin: 50% 0%;
-webkit-animation-timing-function: ease-in-out;
}
#-webkit-keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
}
10% {
-webkit-transform: rotate(10deg);
}
20% {
-webkit-transform: rotate(20deg);
}
30% {
-webkit-transform: rotate(10deg);
}
40% {
-webkit-transform: rotate(5deg);
}
50% {
-webkit-transform: rotate(0deg);
}
60% {
-webkit-transform: rotate(-5deg);
}
70% {
-webkit-transform: rotate(-10deg);
}
80% {
-webkit-transform: rotate(-20deg);
}
90% {
-webkit-transform: rotate(-10deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
<img class="bellImg" src="img/bell.png">
There are a few problems in your code:
The animation-timing-function is specified as ease-in-out. This indicates that the animation starts and end slowly but has more speed in between. For a graceful and equal move, this should be set to linear.
This is what MDN says about ease-in-out timing function:
This keyword represents the timing function cubic-bezier(0.42, 0.0, 0.58, 1.0). With this timing function, the animation starts slowly, accelerates then slows down when approaching its final state. At the beginning, it behaves similarly to the ease-in function; at the end, it is similar to the ease-out function.
There is no value called linear for animation-direction.
The splits are not equal. That is, for some 10% gap it is rotating by 10 degree whereas for others it is rotating only by 5 degree. Make the splits equal.
The below snippet with all corrections done produces a smooth animation.
.bellImg {
height: 20px;
width: 20px;
position: absolute;
right: 10px;
top: 18px;
-webkit-animation-name: rotate;
animation-delay: 3s;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal;
-webkit-transform-origin: 50% 0%;
-webkit-animation-timing-function: linear; /* or make your custom easing */
}
#-webkit-keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(20deg);
}
75% {
-webkit-transform: rotate(-20deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
<img class="bellImg" src="https://cdn1.iconfinder.com/data/icons/freeline/32/bell_sound_notification_remind_reminder_ring_ringing_schedule-48.png">
Setting the animation's speed to depend on the position (that is, slow down as it reaches the extremes and quicken up in the middle) is impossible to achieve with pure CSS (even if we add extra elements).
For setting the animation's speed depending on its position, one option would be to do the following:
Add the image into a container element. Animate it such that it rotates from 20deg to -40deg.
Make the animation on the parent start earlier than the child by 1/3rd of the animation duration of both. That is, reduce the delay on parent by 0.66s. This is done to get the parent to offset initial rotation on the child. The difference is 1/3rd of animation duration because it is the time taken by parent to come to 0deg.
Change the keyframes for the image's animation such that the rotation is from -20deg to 40deg.
Set the animation-direction as alternate for both so that they go in forward direction for first iteration, in reverse for the next and so on.
Set the animation-timing-function as ease-in-out so that it slows down as it approaches the extremes. The effect is more apparent when the animation duration is increased.
.container {
position: absolute;
height: 20px;
width: 20px;
/* right: 10px; commented for demo */
top: 18px;
transform: rotate(20deg);
animation-name: rotate-container;
animation-delay: 2.33s;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
transform-origin: 50% 0%;
animation-timing-function: ease-in-out;
}
.bellImg {
height: 100%;
width: 100%;
transform: rotate(-20deg);
animation-name: rotate;
animation-delay: 3s;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
transform-origin: 50% 0%;
animation-timing-function: ease-in-out;
}
#keyframes rotate {
0% {
transform: rotate(-20deg);
}
100% {
transform: rotate(40deg);
}
}
#keyframes rotate-container {
0% {
transform: rotate(20deg);
}
100% {
transform: rotate(-40deg);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='container'>
<img class="bellImg" src="https://cdn1.iconfinder.com/data/icons/freeline/32/bell_sound_notification_remind_reminder_ring_ringing_schedule-48.png">
</div>
Prefix-free library is used in the snippet only to avoid browser prefixes.
The equation involved in the movement of a pendulum is a sinusoidal movement.
You can get this movement with the following animation
.base {
height: 600px;
width: 10px;
position: absolute;
animation: base 10s infinite linear;
background-color: lightgray;
transform: translateX(588px);
}
#keyframes base {
from {transform: translateX(77px);}
to {transform: translateX(760px);}
}
.element {
height: 10px;
width: 10px;
background-color: green;
border-radius: 100%;
animation: element 10s infinite;
transform: translateY(553px);
}
#keyframes element {
from {transform: translateY(294px); animation-timing-function: ease-out;}
25% {transform: translateY(36px); animation-timing-function: ease-in;}
50% {transform: translateY(294px); animation-timing-function: ease-out;}
75% {transform: translateY(553px); animation-timing-function: ease-in;}
to {transform: translateY(294px);}
}
.ref {
width: 800px;
height: 600px;
background-image: url(http://i.stack.imgur.com/Fx4bR.png);
background-size: cover;
}
<div class="base">
<div class="element">
</div>
</div>
<div class="ref"></div>
I had to use some hand-worked values to adjust for the background-image, but the key idea is in the timing functions.
If the preset function is not what you want, you can set a cubic bezier and adjust it as you want.
.base {
height: 600px;
width: 10px;
position: absolute;
animation: base 10s infinite linear;
background-color: lightgray;
transform: translateX(588px);
}
#keyframes base {
from {transform: translateX(77px);}
to {transform: translateX(760px);}
}
.element {
height: 10px;
width: 10px;
background-color: green;
border-radius: 100%;
animation: element 10s infinite;
transform: translateY(553px);
}
#keyframes element {
from {transform: translateY(294px);
animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
25% {transform: translateY(36px);
animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
50% {transform: translateY(294px);
animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
75% {transform: translateY(553px);
animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
to {transform: translateY(294px);}
}
.ref {
width: 800px;
height: 600px;
background-image: url(http://i.stack.imgur.com/Fx4bR.png);
background-size: cover;
}
<div class="base">
<div class="element">
</div>
</div>
<div class="ref"></div>
This is the image used for reference
And this would be the 2 timing functions applied to a pendulum
.test {
height: 400px;
width: 10px;
background-color: lightgreen;
display: inline-block;
margin: 10px 100px;
transform-origin: center top;
}
.anim1 {
animation: oscil1 6s infinite;
}
.anim2 {
animation: oscil2 6s infinite;
}
#keyframes oscil1 {
from {transform: rotate(0deg); animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
25% {transform: rotate(20deg); animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
50% {transform: rotate(0deg); animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
75% {transform: rotate(-20deg); animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
to {transform: rotate(0deg);}
}
#keyframes oscil2 {
from {transform: rotate(0deg); animation-timing-function: ease-out;}
25% {transform: rotate(20deg); animation-timing-function: ease-in;}
50% {transform: rotate(0deg); animation-timing-function: ease-out;}
75% {transform: rotate(-20deg); animation-timing-function: ease-in;}
to {transform: rotate(0deg);}
}
<div class="test anim1"></div>
<div class="test anim2"></div>
I haven't used CSS here, but since (it seems like) you just want to avoid libraries, I've implemented it in native JS. It uses the Math.sin() method to tween the values smoothly. As you can see, the effect is very smooth and requires very little code.
var img = document.querySelector( '.bellImg' ),
start = 0;
function sine(){
img.style.transform = "rotate(" + 20 * Math.sin( start ) + "deg)";
start += 0.05;
setTimeout(sine, 1000/30)
}
setTimeout( sine, 3000 );
.bellImg {
height: 20px;
width: 20px;
position: absolute;
left: 10px;
top: 18px;
}
<img class="bellImg" src="https://cdn1.iconfinder.com/data/icons/freeline/32/bell_sound_notification_remind_reminder_ring_ringing_schedule-48.png">
Hope this helps!

CSS3 Animation works in Brackets live preview but not when live on my Site

I am using this spinner on my site.
For those unfamiliar with brackets live preview I believe that the editor serves up the site from a temporary http server and updates whenever there is a change in the code.
Whenever I check the site through this feature the spinner works. the same goes for if I go to my website at www.tylererickson.com within Brackets' custom Google Chrome window, however if opened in a normal Chrome window the spinner doesn't animate.
Any help is aprreciated, thanks in advance.
Code:
HTML
<div class="loader">
<div class="inner one"></div>
<div class="inner two"></div>
<div class="inner three"></div>
</div>
CSS
.loader {
position: absolute;
top: calc(50% - 32px);
left: calc(50% - 32px);
width: 64px;
height: 64px;
border-radius: 50%;
perspective: 800px;
}
.inner {
position: absolute;
box-sizing: border-box;
width: 100%;
height: 100%;
border-radius: 50%;
}
.inner.one {
left: 0%;
top: 0%;
animation: rotate-one 1s linear infinite;
border-bottom: 3px solid #EFEFFA;
}
.inner.two {
right: 0%;
top: 0%;
animation: rotate-two 1s linear infinite;
border-right: 3px solid #EFEFFA;
}
.inner.three {
right: 0%;
bottom: 0%;
animation: rotate-three 1s linear infinite;
border-top: 3px solid #EFEFFA;
}
#keyframes rotate-one {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
#keyframes rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
#keyframes rotate-three {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
I think you will need to add browser vendor prefix for chrome in order to work. If you take a look the current chrome for animation to support need to have -webkit in front of keyframes. Take a look here: http://caniuse.com/#feat=css-animation
At the end you will have something like this:
#-webkit-keyframes rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
And then will use it like this:
.inner.two {
right: 0%;
top: 0%;
-webkit-animation: rotate-two 1s linear infinite;
animation: rotate-two 1s linear infinite;
border-right: 3px solid #EFEFFA;
}
You will need to make this for all others animation also. I just give example for one of them
The reason in Codepen the animation works without the prefixes is because Codepen uses Prefixfree and it automatically applies the needed prefixes for the browser.
You need to add the prefixes either manually or add the Prefixfree jQuery plugin to your page.
I recommend set the prefixes for the loader manually and not with the plugin, the reason is the loading animation should be the first to be loaded in your page and using the prefix plugin means the user has to wait for the jQuery and the prefix plugin to be loaded first, and that will cause a delay in loading the animation.
So add the following prefixes and it will work as expected.
.inner.one {
-webkit-animation: rotate-one 1s linear infinite;
-moz-animation: rotate-one 1s linear infinite;
animation: rotate-one 1s linear infinite;
}
.inner.two {
-webkit-animation: rotate-two 1s linear infinite;
-moz-animation: rotate-two 1s linear infinite;
animation: rotate-two 1s linear infinite;
}
.inner.three {
-webkit-animation: rotate-three 1s linear infinite;
-moz-animation: rotate-three 1s linear infinite;
animation: rotate-three 1s linear infinite;
}
And for the #keyfames:
/*Spinner Styles*/
#keyframes rotate-one {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
#-moz-keyframes rotate-one {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
#-webkit-keyframes rotate-one {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
#keyframes rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
#-moz-keyframes rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
#-webkit-keyframes rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
#keyframes rotate-three {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
#-moz-keyframes rotate-three {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}
#-webkit-keyframes rotate-three {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}