I am trying to achieve a simple animation with css.
My markup has the following structure:
<main>
<left />
<middle />
<right />
</main>
I want my animation to do the following sequence:
// second 0 - 2: Do nothing
// second 2 - 3: hide the middle element, move the left element to the right, and the right element to the left.
// second 3 - 4: Rotate the main element 360 degrees
// second 4 - 6: Do nothing
// second 6 - 7: show the middle element, move the left element to the left, and the right element to the right.
// Repeat
Here is my css code:
#keyframes hideMiddle {
28.57%, 42.85% {opacity: 0;}
85.71%, 100% {opacity: 1;}
}
#keyframes moveRight {
28.57%, 42.85% { transform: translateX(15%);}
85.71%, 100% {transform: translateX(0%);}
}
#keyframes moveLeft {
28.57%, 42.85% {transform: translateX(-22%);}
85.71%, 100% {transform: translateX(0%);}
}
#keyframes rotateMain {
42.85%, 57.14% {transform: rotate(360deg);}
}
Everything works until I add the rotateMain animation at which point it seems to run from the start of the animation rather than where its set to start as well as it seems to do an extra rotation. Any help is appreciated, thanks a lot.
So after playing around a bit I figured it out, I'm leaving an answer to the question in case anyone finds some use in this although its not the best formulated question:
So the problem was in the rotate keyframes, I used this:
#keyframes rotateMain {
42.85%, 57.14% {transform: rotate(360deg);}
}
Thinking it would rotate the figure 360 degrees from 42.85% to 57.14%.
The following code actually achieves what I wanted:
#keyframes rotateMain {
42.85% {transform: rotate(0deg);}
57.14% {transform: rotate(360deg);}
100% {transform: rotate(360deg);}
}
Related
I'm using CSS transform translateX to move a Gif from left to right. The gif stops and belches towards the end of the Gif animation but the Gif is still being translated along the X co-ordinate, so it doesn't look good!
How can I add a pause/delay at the end of the translateX.
There's a similar question on Stackoverflow regarding a Rotate, and the answer is the following code:
66%, 100% {
transform:rotatey(0deg);
}
But for the life of me I can't figure out how to apply to mine.
.gif-image {
width: 30%;
animation-name: slideLeftToRight;
animation-duration: 20s;
animation-iteration-count: infinite;
}
#keyframes slideLeftToRight {
from {transform: translateX(0px)}
to {transform: translateX(400px)}
}
body{
background-color: #6dba94;
}
<div class="container">
<img class="gif-image" src="https://cdn.dribbble.com/users/672882/screenshots/1972683/character-rig-800x600.gif" />
</div>
This is an interesting one since you can't use a transition delay quite the same as in most circumstances since the GIF never stops. So your case basically boils down to timing up the animation to match with the GIF timing. This is going to be hard to do, especially if you didn't make the GIF yourself. (If you did, maybe it'd be easier for you to tell exactly when the guy starts and stops walking, in milliseconds.)
That said, hard does not mean impossible.
Important note before we start: The GIF is gonna keep playing over and over, even if you update your code in JS Fiddle or CodePen or a Stack Snippet or what have you. So you can end up thinking your animation timing is all off when it's actually not. In testing this, I copied the URL I was working from in CodePen and then kept closing the tab, reopening a new one, and pasting the URL into there to reload it with the GIF starting from its beginning. This is tedious, but I don't know a better way.
Anyway...
First you gotta figure out how long the GIF lasts because it'll make our life a million times easier to base the animation duration around the GIF's duration. I was guessing initially that it'd be a nice round number like exactly 5 seconds, but in testing it seemed to get off after a few iterations, like it was actually slightly longer. I'm ballparking it at 5.15 seconds.
So let's make our guy walk to the right when he's done belching. First we gotta figure out how long exactly he takes before he starts walking. (If you know this number exactly, your life will be way easier. I had to use guess and check.)
With some testing, I figured out he starts walking approximately 42% of the way into the GIF, or about 2163ms into it, if the GIF is 5.15 seconds long (5150ms). So we don't start our translation until that point:
#keyframes animationName {
0% {
transform: translateX(0px);
}
42% {
transform: translateX(0px);
}
100% {
transform: translateX(200px);
}
}
That basically gives us this:
.gif-image {
width: 250px;
animation-iteration-count: infinite;
animation-name: slideLeftToRightRepeating;
animation-duration: 5.15s;
}
#keyframes slideLeftToRightRepeating {
0% {
transform: translateX(0px);
}
42% {
transform: translateX(0px);
}
100% {
transform: translateX(200px);
}
}
body {
background-color: #6dba94;
}
<div class="container">
<div><img class="gif-image" src="https://cdn.dribbble.com/users/672882/screenshots/1972683/character-rig-800x600.gif" /></div>
</div>
Once we get that part down, if you want him to keep walking sideways like you have in your question with a long animation duration, it's just a matter of multiplying our animation duration by however many times you want to repeat the motion, and then dividing our percentages by that same amount.
So let's say you want to have him repeat the animation five times. Our animation duration now becomes (5 * 5.15s) = 20.75s.
Then, in our percentages, every 20% of the animation (because we're dividing it in fifths) will be a repeat of the pattern we established above. So at the 20% mark, we have the same effect as at the 100% mark above.
We figured out he starts walking around 42% of the way through, so we take 42% of 20% to get 8.4%. Our keyframes now look like this:
#keyframes animationName {
0% {
transform: translateX(0px);
}
8.4% {
transform: translateX(0px);
}
20% {
transform: translateX(200px);
}
28.4% {
transform: translateX(200px);
}
40% {
transform: translateX(400px);
}
.....
}
In practice, this proved to be not quite right (I guess my 42% estimation isn't perfect). Revising our numbers a bit, I came up with 0%, 11.5%, 20%, 31.5%, etc.
At the end, we have 100% { transform: translateX(1000px); }. That's a 200px translation five times.
Here's a pretty good starting spot where things go decently well, but the timing isn't exact. I'll leave it up to you to mess with it to get the numbers exactly right and also to adjust the distance he walks each time to fit your circumstance. Hopefully this helps.
Note that I think your life will be easier if you set the width of the GIF as well as the translation distance in fixed units, otherwise you may find that with relative units like percentages that your guy appears to either be walking in place or taking huge bounds across the screen depending how wide it is.
.gif-image {
width: 250px;
animation-iteration-count: infinite;
animation-duration: 20.75s;
animation-name: slideLeftToRightSlowly;
}
#keyframes slideLeftToRightRepeating {
0% {
transform: translateX(0x);
}
42% {
transform: translateX(0px);
}
100% {
transform: translateX(200px);
}
}
#keyframes slideLeftToRightSlowly {
0% {
transform: translateX(0px);
}
11.5% {
transform: translateX(0px);
}
20% {
transform: translateX(200px);
}
31.5% {
transform: translateX(200px);
}
40% {
transform: translateX(400px);
}
51.5% {
transform: translateX(400px);
}
60% {
transform: translateX(600px);
}
71.5% {
transform: translateX(600px);
}
80% {
transform: translateX(800px);
}
91.5% {
transform: translateX(800px);
}
100% {
transform: translateX(1000px);
}
}
body {
background-color: #6dba94;
}
<div class="container">
<div><img class="gif-image" src="https://cdn.dribbble.com/users/672882/screenshots/1972683/character-rig-800x600.gif" /></div>
</div>
I seem to have an issue with the webkit animations. I added an overlay spinner. This one shows fine on every browser (Mozilla, IE, Edge, Chrome). On Andriod and iPhone/iPad the animation is not fired. Am I missing something in my code?
In CSS I added following to the div of the element:
-webkit-animation-name:webkit-rotate-scale;
-webkit-animation-duration:0.75s;
-webkit-animation-direction:normal;
-webkit-animation-delay:0s;
-webkit-animation-iteration-count:infinite;
-webkit-animation-timing-function:linear;
-webkit-animation-play-state:running;
and
#-webkit-keyframes webkit-rotate-scale {
0% {-webkit-transform: rotate(0deg) scale(1);}
50% {-webkit-transform: rotate(180deg) scale(.5);}
100% {-webkit-transform: rotate(360deg) scale(1);}
}
Off course I added the standard (no webkit) alternatives also.
Can someone tell me what I'm missing?
The div where I am showing it in has display: inline-block.
Thanks in advance!
Kind regards,
Jerry
I am trying to have an element scale up from 0 on page load, but that element needs to be rotated. Seems like a simple thing, but it seems to apply the rotation after the animation finishes:
#-webkit-keyframes scale{
0%{-webkit-transform: scale(0);}
100%{-webkit-transform: scale(1);}
}
div{
-webkit-transform: rotate(30deg);
-webkit-animation: scale 2s;
}
http://jsfiddle.net/mildfuzz/wnpVp/
You need to use the transform shorthand within the #keyframes rule, as your rotate() function is outside the rule and thus not animating like you expected.
http://jsfiddle.net/wnpVp/3
I want to animate two (or more) CSS transform properties separately using keyframe animation like this:
#keyframes translatex {
100% {
transform: translateX(100px);
}
}
#keyframes rotatez {
100% {
transform: rotateZ(80deg);
}
}
HTML:
<div class="rect"></div>
The translatex animation should start with a 0s delay and last for 5 seconds. The rotatez animation should start with a 1s delay and last for 3 seconds. The .rect element starts moving, then after 1 second it starts rotating, then after 3 seconds it stops rotating and after 1 more second it finishes its movement.
Apply animation:
.rect {
animation-name: translatex, rotatez;
animation-duration: 5s, 3s;
animation-timing-function: ease, ease-in-out;
animation-delay: 0s, 1s;
animation-direction: forward, forward;
}
The problem is that only the rotatez animation is applied.
Are there ways to implement the animation using only CSS, such as keyframe animation or transitions, or do I need JavaScript and requestAnimationFrame?
Yes, it is possible. Instead of calling two animation-names, create only one animation with both actions inside:
#keyframes translateXandZ {
100% {
transform: translateX(100px) rotateZ(80deg);
}
}
Look at Google's "Animate your HTML5" presentation.
Here is a workaround, even though it is a bit of a coarse version:
#-webkit-keyframes translateXandZ {
0% {-webkit-transform: translateX(0px) rotateZ(0deg);}
2% {-webkit-transform: translateX(1px) rotateZ(0deg);}
5% {-webkit-transform: translateX(3px) rotateZ(0deg);}
20% {-webkit-transform: translateX(20px) rotateZ(0deg);}
80% {-webkit-transform: translateX(80px) rotateZ(80deg);}
95% {-webkit-transform: translateX(97px) rotateZ(80deg);}
98% {-webkit-transform: translateX(99px) rotateZ(80deg);}
100% {-webkit-transform: translateX(100px) rotateZ(80deg);}
}
Your animation is linear, but to make it ease-in-out, I played with the beginning and ending of the animation. It's still not perfect, but this is the only way I see how you could get what you want.
I just set an animation to a div and it succeeded.
Now I want to get it proved because its delay is too short!
so how can I add the delayed time between animation (0% to 25%) and animation (25% to 50%)
here is the code:
#flow{
position:absolute;
-webkit-animation:mymove 10s ease-in-out;
-webkit-animation-iteration-count:3;
-webkit-animation-delay:1s;
}
#-webkit-keyframes mymove
{
0%{left:5px;}
25%{left:127px;}
50%{left:249px;}
75%{left:371px;}
100%{left:5px;}
}
everyone!Thanks for your attention !I have found the answer but I don't know the Api of the definition of percentage in keyframes!And if you know sth about it ,just give me a hand ,thanks a lot!
#-webkit-keyframes mymove
{
0%{left:5px;}
25%{left:127px;}
26%{left:127px;}
27%{left:127px;}
28%{left:127px;}
29%{left:127px;}
30%{left:127px;}
31%{left:127px;}
32%{left:127px;}
33%{left:127px;}
34%{left:127px;}
35%{left:127px;}
50%{left:249px;}
75%{left:371px;}
100%{left:5px;}
}
I don't think you can delay the single parts of an animation. What you could do, is to use two animations and start them with a delay.
#flow{
position:absolute;
-webkit-animation:
mymove_first 10s 0s 10 ease-in-out,
mymove_second 10s 2s 10 ease-in-out;
}
#-webkit-keyframes mymove_first
{
0%{left:5px;}
25%{left:127px;}
}
#-webkit-keyframes mymove_second
{
50%{left:249px;}
75%{left:371px;}
100%{left:5px;}
}
I ran into this problem, as far as I can find, without jQuery you can't delay the frames.
You can delay the start of the animation.
You can also get the animation to finish the same state as the original frame.
The mean one I use, is being able to do multiple animations, for example:
Your div:
<div id="bannerImg" class="banner-RunAnimation"></div>
Run animation
.RunAnimation {
-webkit-animation: animation1 3s 0s 1 ease-in-out,
animation2 5s 5s 1 ease-out forwards;
}
Animations:
#-webkit-keyframes animation1 {
0% {-webkit-transform: translateY(-0px);}
50% {-webkit-transform: translateY(-150px);}
100% {-webkit-transform: translateY(-150px);
opacity:0;}
}
#-webkit-keyframes animation2 {
0% {transform: translateY(-0px);}
100% {transform: translateY(-150px);}
}
By delaying the animations and using opacity, you can do qutie a few things, if this doesn't help look into jQuery
You can pause it playing with the percentages ( following your example ):
#-webkit-keyframes mymove
{
0%{left:5px;}
25%{left:127px;}
35%{left:127px;}
50%{left:249px;}
75%{left:371px;}
100%{left:5px;}
}
you dont need to put all the percentages between 25% and 35%, the browser is ignoring them.
you move from 0 to 25% from pixel 5 to 127, if your animation is 10 seconds it will take 2.5 seconds to do that, then pause 1 second between 25% to 35% since its the same pixel it wont move then continue to the next animation to pixel 249, it will take 1.5 seconds and so on...
hope this helps!