I want to flip an image instantly every 1000ms. I'm trying but the animation does what it's supposed to do (gradually flip the picture). If i can flip instantly the picture it will give the idea of a walking duck. I know I can use setInterval() but I'd rather do this in CSS only.
.duck {
position: absolute;
animation: flip-me;
animation-duration: 1000ms;
animation-direction: alternate;
animation-iteration-count: infinite;
}
#keyframes flip-me {
0% { transform: scaleX(1) }
100% { transform: scaleX(-1) }
}
You can consider steps()
img {
animation: flip-me 2s steps(1) infinite;
}
#keyframes flip-me {
50% { /*Pay attention: it's 50% not 100% !!*/
transform: scaleX(-1)
}
}
/*no need 0% or 100% state as they be set by default to scaleX(1)*/
<img src="https://picsum.photos/200/200?image=1069">
Related
I've been stuck on this problem for 3 days and have scoured the Internet for a solution, but haven't been able to find one that works yet.
I have an animation of a cartoon rocket flying across a screen. The rocket has 4 chained keyframe animations applied to it:
1.) "launch" moves the rocket from off the left side of the screen, across to the right
2.) "rightself" rotates the rocket so it's pointing up
3.) "descend" moves the rocket down towards a planet
4.) "shrink" makes the rocket smaller as it approaches the planet's surface
I can't add a video here, but here are links to how it should and shouldn't look:
How it should look:
https://twitter.com/planet_katie/status/1415739110505996291
How it's glitching on all iOS browsers and desktop Safari:
https://twitter.com/planet_katie/status/1418312787906998275
Game Link, if you want to try yourself: http://www.codeeverydamnday.com/projects/rocketblaster/index.html
The rocket animation runs smoothly on desktop Chrome and Firefox, but glitches in Safari. It also runs smoothly on Android phones, but again glitches on every browser I've tried on an iPhone. The iPhone emulator in Chrome's dev tools shows it running smoothly as well, so I'm not sure why it's not translating to the iPhone itself.
Things I have tried:
Changing my svg images to png's, as I read that sometimes svg's behave unexpectedly
Added all of the proper -webkit- prefixes
Condensing the 4 animations into 1
Using the longhand format when adding my CSS animation on my element (animation-name, animation-duration, animation-iteration-count, etc) instead of the shorthand format
Including both the 0% and 100% keyframes for each animation
Adding a 0.01 second delay to the first animation (read somewhere that this helped someone else)
So far, no luck. Anyone able to take a look at my code and see if I'm missing anything? Note: I have removed the -moz-, -ms- and -o- prefixes for brevity, but they are in my code as well.
#rocketfire {
background-color: red;
position: absolute;
top: 100px;
left: -320px;
height: 200px;
-webkit-animation: launch 4s ease-in-out 0.01s 1 forwards,
rightself 2s ease-in-out 3.5s 1 forwards,
shrink 3.5s ease-in-out 4s 1 forwards, descend 4s ease-in-out 5s 1 forwards;
animation: launch 4s ease-in-out 1 forwards,
rightself 2s ease-in-out 3.5s 1 forwards,
shrink 3.5s ease-in-out 4s 1 forwards, descend 4s ease-in-out 5s 1 forwards;
}
#-webkit-keyframes launch {
0% {
-webkit-transform: translateX(-0px);
}
100% {
-webkit-transform: translateX(1050px);
}
}
#keyframes launch {
0% {
transform: translateX(-320px);
}
100% {
transform: translateX(1050px);
}
}
#-webkit-keyframes rightself {
0% {
-webkit-transform: translateX(1050px) rotate(0deg);
}
100% {
-webkit-transform: translateX(1050px) rotate(-82deg);
}
}
#keyframes rightself {
100% {
transform: translateX(1050px) rotate(-82deg);
}
}
#-webkit-keyframes descend {
0% {
-webkit-top: 0px;
}
100% {
-webkit-top: 270px;
}
}
#keyframes descend {
100% {
top: 270px;
}
}
#-webkit-keyframes shrink {
0% {
-webkit-transform: translateX(1050px) rotate(-82deg) scale(1);
}
100% {
-webkit-transform: translateX(1050px) rotate(-82deg) scale(0.5);
}
}
#keyframes shrink {
100% {
transform: translateX(1050px) rotate(-82deg) scale(0.5);
}
}
<img id="rocketfire" src="images/rocketfireright.png" />
I think you shouldn’t need the -webkit versions of the animations, so removing those will make the CSS easier to debug. I found a couple of inconsistencies and missing values. Cleaned up, the CSS looks like the following:
#rocketfire {
background-color: red;
position: absolute;
top: 100px;
left: -320px;
height: 200px;
animation: launch 4s ease-in-out 1 forwards,
rightself 2s ease-in-out 3.5s 1 forwards,
shrink 3.5s ease-in-out 4s 1 forwards,
descend 4s ease-in-out 5s 1 forwards;
}
#keyframes launch {
0% {
transform: translateX(-320px);
}
100% {
transform: translateX(1050px);
}
}
#keyframes rightself {
0% {
transform: translateX(1050px) rotate(0deg);
}
100% {
transform: translateX(1050px) rotate(-82deg);
}
}
#keyframes descend {
0% {
top: 0px;
}
100% {
top: 270px;
}
}
#keyframes shrink {
0% {
transform: translateX(1050px) rotate(-82deg) scale(1);
}
100% {
transform: translateX(1050px) rotate(-82deg) scale(0.5);
}
}
Try that and see if it fixes it!
What ultimately worked for me was combining the four animations into one, like this:
#keyframes launch {
30% {transform: translateX(1050px) rotate(0);}
50% {transform: translateX(1050px) scale(1) rotate(-82deg); top: 100px;}
80% {transform: translateX(1050px) scale(0.5) rotate(-82deg);}
100% {transform: translateX(1050px) scale(0.5) rotate(-82deg); top: 270px;}
}
Seems like Safari had a problem trying to run multiple keyframes animations at once.
This may be a dumb question (haven't done JS/HTML in a bit). I want this animation to be smooth all the way through but for some reason, it is stopping in the middle for a short period of time then resuming. Adding more steps to try and smooth the transition only seems to make is pause for longer. Is there a fix for this?
#under {
color: black;
font-size: 28px;
animation-duration: 4s;
animation-name: example;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: ease-in-out;
}
#keyframes example {
0% {
transform: translateX(-330px);
}
50% {
transform: scaleX(3);
}
100% {
transform: translateX(330px);
}
}
<body>
<div id="under">
<p> - </p>
</div>
</body>
To keep things moving evenly, you need to define your scaleX values at 0% and 100%. In addition, I changed your timing function from ease-in-out to linear. At 50%, translateX is already at 0 since you defined the start and end values. For consistency, I added the 0 value at 50%.
#under {
background-color: #000;
color: white;
animation-duration: 4s;
animation-name: example;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: linear;
width: 100px;
height: 50px;
}
#keyframes example {
0% {
transform: scaleX(1) translateX(-330px);
}
50% {
transform: scaleX(3) translateX(0);
}
100% {
transform: scaleX(1) translateX(330px);
}
}
<div id="under"></div>
How can I repeat a spinning animation x times before easing it out ?
For instance :
#spin-please {
background: green;
width: 50px;
height: 50px;
animation: spin 3s infinite ease-in-out;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
49% {
transform: rotate(359deg);
}
50% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="spin-please">
</div>
My animation right now is not very smooth at all (as you can see between the 1st and 2nd rotation), and there is an easing between the 2 rotations, which I want only at the start of the first of the rotation and at the end of the second (or the third if I choose to go with an additional rotation).
Easing in ==> rotation 1 ==> rotation 2 ==> easing out
Is this doable with CSS ?
Instead of repeating the animation infinite times, you can specify a number of repetitions like this:
animation: spin 3s 3 ease-in-out; /* 3secs, repeat 3 times */
See animation iteration count for more examples.
Also useful to see the animation short-hand docs to set all the properties at once (like your code does)
I am not sure what the desired outcome you are looking for but I modified the animation to display the spinning happening three times (with some reversal spin as well)
#spin-please {
background: green;
width: 50px;
height: 50px;
/* #keyframes duration | timing-function | delay |
iteration-count | direction | fill-mode | play-state | name
*/
animation: 1s 3 spin;
animation-timing-function: ease-in, linear, ease-out;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="spin-please">
</div>
The problem is totally not because your animation isn't smooth,
the problem with keyframes, according to this code
49% {
transform: rotate(359deg);
}
50% {
transform: rotate(0deg);
}
Your animation have to do 360deg rotation in very short time which is 1% ( between 49% - 50%) for any animation-timing-function value your animation is not smooth, Try this code :
#spin-please {
background: green;
width: 50px;
height: 50px;
animation: spin 3s ease infinite;
}
#keyframes spin {
0% {
animation-timing-function: ease-out;
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
animation-timing-function: ease-in;
transform: rotate(360deg);
}
}
<div id="spin-please">
</div>
Remember you can change your animation-timing-function in your keyframes. more details about animation-timing-function.
#spin-it {
background: green;
width: 50px;
height: 50px;
animation: spin 1.5s ease infinite;
}
#keyframes spin {
0% {
animation-timing-function: ease-out;
transform: rotate(0deg);
}
25% {transform: rotate(90deg);}
50% {
transform: rotate(180deg);
}
75% {transform: rotate(270deg);}
100% {
animation-timing-function: ease-in;
transform: rotate(360deg);
}
}
<div id="spin-it">
</div>
My version of MMJ's
It goes through 5 steps.
Ease in >>> Turn 1 side >>> Turn 1 side >>> Turn 1 side >>> Turn 1 side >>> Ease out
Is it possible to "restart" a keyframe animation after it's stops with the same animation delay time again?
#keyframes scale {
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
.animated-btn {
animation: scale ease-in 1;
animation-fill-mode:forwards;
animation-duration: .6s;
animation-delay: 11.8s;
}
<a href="" class="btn btn__arrow animated-btn">
Aniamted Button
</a>
Unfortunately it's not possible to set a delay before each animation, but you can set a delay inside the animation. Just let the animation do nothing for a while until you reach a certain percentage.
Here's the updated code.
#keyFrames scale {
90% {
transform: scale(1)
}
95% {
transform: scale(1.3)
}
100% {
transform: scale(1);
}
}
.animated-btn {
display: inline-block;
animation: scale ease-in 1;
animation-fill-mode: forwards;
animation-duration: 12.4s;
animation-delay: 0s;
animation-iteration-count: infinite;
/* Or the shorthand:
animation: scale 1.4s 0s infinite ease-in forwards;
*/
}
Yes you just need to use the animation-iteration-count property.
You can set its value to infinite.
How do I combine these two animations (translate & buttonFade) so that they both affect the same image ? Both animations work seperatley but not together. Is there a way to combine the two? (I have omitted the -moz- , -o- etc purposefully to make it easier to read, I have tried adding these and it makes no difference)
translate {
-webkit-animation: moveLeft 1s forwards;
}
#-webkit-keyframes moveLeft {
0% {-webkit-transform: translateX(0px)}
100% {-webkit-transform: translateX(100px)}
}
.intro-button{
position:absolute;
top: 350px;
left: 625px;
opacity: 0;
-webkit-animation: buttonFade 3s 1 forwards;
-webkit-animation-delay: 2s;
}
#-webkit-keyframes buttonFade {
0% {opacity: 0;}
80% {opacity: 0;}
100% {opacity: 1;}
}
Any help would be much appreciated!
You can list multiple animations by separating them with a comma, as such you can simply call moveLeft from your CSS for .intro-button and remove your CSS for translate (which by the way is not a valid selector).
You'll also want to add a other value for the animation delay, which should be first animation delay + first animation duration (4s)
Demo Fiddle
Change your CSS thusly:
#-webkit-keyframes moveLeft {
0% {
-webkit-transform: translateX(0px)
}
100% {
-webkit-transform: translateX(100px)
}
}
.intro-button {
position:absolute;
top: 350px;
left: 625px;
opacity: 0;
-webkit-animation: buttonFade 3s 1 forwards, moveLeft 1s forwards;
-webkit-animation-delay: 2s, 4s;
}
#-webkit-keyframes buttonFade {
0% {
opacity: 0;
}
80% {
opacity: 0;
}
100% {
opacity: 1;
}
}
You can actually concatenate the animation property further:
-webkit-animation: buttonFade 3s 2s 1 forwards, moveLeft 1s 4s forwards;
Removing the need to set animation duration separately The shorthand foranimation is:
animation: animation-name animation-duration animation-timing-function animation-delay animation-iteration-count animation-direction animation-fill-mode;