I'm trying to implement this simple animation for a rock-paper-scissors game I'm developing:
http://jsfiddle.net/franciov/kbngz27s/1/
#keyframes arm-out {
from {
left: 0em;
}
to {
left: 5em;
}
}
.player > .arm.out {
animation-name: arm-out;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
Basically, I want the player to:
pull back his arm when the game loads (arm-in animation)
show his arm when the 'Play' button is clicked (arm-out animation) Note: I would like the player to show the arm after a while, at the moment this is implemented with a window.setTimeout but I would like to use the animation-delay property
show the hand shape after a delay (reveal animation, in JSFiddle the shape is always 'scissors')
The animation-delay for the point (3) works well:
#keyframes reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.hand.reveal {
animation-name: reveal;
animation-delay: 0.5s;
animation-duration: 0.2s;
animation-fill-mode: forwards;
}
but when I try to add a animation-delay property for the point (2), things does not work properly anymore, as you can try on the next JSFiddle:
http://jsfiddle.net/franciov/kbngz27s/2/
.player > .arm.out {
animation-name: arm-out;
animation-delay: 0.8s; /* This is not working properly */
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
Any ideas?
I tried the JSFiddles above on Chrome 45.0.2454.101 and Firefox 43.0a2.
You simply have to add left: 0; to .arm.out, because at the moment you click the button, it removes the in class and you have left: 5em; in your arm class.
Set the left position of "out arm" to zero then let the animation do the job.
.player > .arm.out {
left: 0; /* Add this one. */
animation-name: arm-out;
animation-delay: 0.8s; /* This is working for me (Chrome 45) */
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
Fiddle : http://jsfiddle.net/kbngz27s/3/
(Added some time to .hand.reveal so it doesn't appear before the arm). Strangely it sometimes fails as you say, but not every time...
Related
I'm running an animation on some elements that are set to opacity: 0; in the CSS. The animation class is applied onClick, and, using keyframes, it changes the opacity from 0 to 1 (among other things).
Unfortunately, when the animation is over, the elements go back to opacity: 0 (in both Firefox and Chrome). My natural thinking would be that animated elements maintain the final state, overriding their original properties. Is this not true? And if not, how can I get the element to do so?
The code (prefixed versions not included):
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; }
50% { transform:scale(1.2); opacity:0.5; }
100% { transform:scale(1.0); opacity:1.0; }
}
Try adding animation-fill-mode: forwards;. For example, the shorthand would be used like this:
-webkit-animation: bubble 1.0s forwards; /* for less modern browsers */
animation: bubble 1.0s forwards;
If you are using more animation attributes the shorthand is:
animation: bubble 2s linear 0.5s 1 normal forwards;
This gives:
bubble animation name
2s duration
linear timing-function
0.5s delay
1 iteration-count (can be 'infinite')
normal direction
forwards fill-mode (set 'backwards' if you want to have compatibility to use the end position as the final state[this is to support browsers that has animations turned off]{and to answer only the title, and not your specific case})
Available timing-functions:
ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end
Available directions
normal | reverse | alternate | alternate-reverse
IF NOT USING THE SHORT HAND VERSION: Make sure the animation-fill-mode: forwards is AFTER the animation declaration or it will not work...
animation-fill-mode: forwards;
animation-name: appear;
animation-duration: 1s;
animation-delay: 1s;
vs
animation-name: appear;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-delay: 1s;
Use
animation-fill-mode: forwards;
animation-fill-mode: forwards;
The element will retain the style values that is set by the last keyframe (depends on animation-direction and animation-iteration-count).
Note: The #keyframes rule is not supported in Internet Explorer 9 and earlier versions.
Working example
div {
width: 100px;
height: 100px;
background: red;
position :relative;
-webkit-animation: mymove 3ss forwards; /* Safari 4.0 - 8.0 */
animation: bubble 3s forwards;
/* animation-name: bubble;
animation-duration: 3s;
animation-fill-mode: forwards; */
}
/* Safari */
#-webkit-keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
/* Standard syntax */
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
<h1>The keyframes </h1>
<div></div>
I had an issue using forwards: at least in Chrome, even after the animation ended, the renderer was still sucking up graphics resources, making the application less responsive.
An approach that does not cause this trouble is by using an EventListener.
CSS animations emit events, so you can use the animationend event to intervene when the animation ends.
CSS
.fade_in {
animation: fadeIn 2s;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
JavaScript
const element = document.getElementById("element-to-be-animated");
element.addEventListener("animationend", () => {
// Set your final state here. For example:
element.style["opacity"] = 1;
}, { once: true });
The option once: true tells the engine to remove the event listener after its execution, leaving your application fresh and clean.
I have created a JSFiddle to show how it works.
Discord has a nicely animated page
https://discordapp.com/
The coins are moving up and down really smoothly. How can I copy this logic for my own images?
I started with this code
img {
animation-name: move;
animation-duration: 2.5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
#keyframes move {
0% {
margin-top: 0px;
}
50% {
margin-top: 10px;
}
100% {
margin-top: 0px;
}
}
<img src="https://gonintendo.com/system/file_uploads/uploads/000/013/369/original/bg-header-earn-coins.png">
When testing the code the image is not moving smoothly. I thought using animation-timing-function: ease-in-out; would do it for me.
Is something missing there?
When it comes to animations, duration and distance moved are highly important. The type of animation is also important. Using margins instead of CSS transforms makes it less likely that the GPU will be used, which is generally better at animating than not using GPU.
Basically, your code is not a faithful recreation of the timing and animation styles as are used on discord. This is closer:
img {
animation-name: move;
animation-duration: 1.5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
animation-direction: alternate;
}
#keyframes move {
0% {
transform: translate3d(0,-4px,0)
}
to {
transform: translate3d(0,4px,0)
}
}
<img src="https://gonintendo.com/system/file_uploads/uploads/000/013/369/original/bg-header-earn-coins.png">
I'm trying to delay the trigger of a CSS animation (not slow down the animation itself, but delay it a few seconds before starting). And the image should not display before the animation runs. I looked through the other questions, and they don't seem to address this.
MY FIDDLE: http://jsfiddle.net/omarel/guh5f8bs/
CSS
.slideRight{
animation-name: slideRight;
-webkit-animation-name: slideRight;
animation-duration: 1s;
-webkit-animation-duration: 1s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
visibility: visible !important;
}
#keyframes slideRight {
0% {
transform: translateX(-150%);
}
100% {
transform: translateX(0%);
}
}
#-webkit-keyframes slideRight {
0% {
-webkit-transform: translateX(-150%);
}
100% {
-webkit-transform: translateX(0%);
}
}
HTML
<div class="slideRight">
HI
</div>
Side note: Also is there a way to get it to work with an <a> tag? Animations don't seem to play nice with this:
<a class="slideRight">
HI
</a>
Delaying the start of the animation is very simple. Simply add the animation-delay property to your code:
.slideRight{
animation-name: slideRight;
animation-duration: 1s;
animation-timing-function: ease-in-out;
visibility: visible !important;
/* New code here: */
animation-delay: 1s;
}
It's important to note that animation-delay only delays the start of the animation from the beginning. If you have a repeating animation, it won't add the delay to the same spot of each loop; only to the very beginning. There's currently no CSS property capable of that kind of looped delay.
All major browsers currently support animation-delay without the need for vendor prefixes.
As for your second question regarding the <a> element: Yes, it can work. The reason it's not working for you now is because <a> elements are inline elements. In order to make it work like you're expecting, add display: inline-block; to the .slideRight{} selector. Ultimately this is what your code will look like:
.slideRight{
animation-name: slideRight;
animation-duration: 1s;
animation-timing-function: ease-in-out;
visibility: visible !important;
/* New code here: */
animation-delay: 1s;
display: inline-block;
}
#keyframes slideRight {
0% {
transform: translateX(-150%);
}
100% {
transform: translateX(0%);
}
}
<a class="slideRight">HI</a>
JSFiddle Example
Add a settimeout function
Hi there, you could add an event listen that get when you mouseover the certain element and then calls the function after 1 second.
$('slideRight').on('mouseover',function(){
window.setTimeout(function(){
$this.addClass('onesecond');
}, 1000); //<-- Delay in milliseconds
});
div {
-webkit-animation-delay: 2s; /* Safari 4.0 - 8.0 */
animation-delay: 2s;
}
Source:
https://www.w3schools.com/cssref/css3_pr_animation-delay.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay
I have multiple divs with animations, created in CSS, on my page. When the last div with animation is finished animating I wish to have the whole sequence to start over. My animations all have different delay times, and animations. I've tried the "animation: infinite" but what that achieves is the each individual animation will run again immediately after the animation has finshed. I need it start from the beginning after all of the animations have completed.
Anyone know how to achieve this?
Sample CSS
.openDiv {
width: 0px;
height: 513px;
background-image: url("CLS-circle-Ring-faded.png");
animation-name: grow;
animation-duration: 2s;
animation-fill-mode: forwards;
animation-delay: 2s;
transition-delay: 10s;
-webkit-animation-name: grow;
-webkit-animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
-webkit-animation-delay: 2s;
-webkit-transition-delay: 10s;
}
#-webkit-keyframes grow {
0% {
width: 0px;
}
100% {
width: 1379px;
}
} /* Standard syntax */#keyframes grow {
0% {
width: 0px;
}
100% {
width: 1379px;
}
}
I'm running an animation on some elements that are set to opacity: 0; in the CSS. The animation class is applied onClick, and, using keyframes, it changes the opacity from 0 to 1 (among other things).
Unfortunately, when the animation is over, the elements go back to opacity: 0 (in both Firefox and Chrome). My natural thinking would be that animated elements maintain the final state, overriding their original properties. Is this not true? And if not, how can I get the element to do so?
The code (prefixed versions not included):
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; }
50% { transform:scale(1.2); opacity:0.5; }
100% { transform:scale(1.0); opacity:1.0; }
}
Try adding animation-fill-mode: forwards;. For example, the shorthand would be used like this:
-webkit-animation: bubble 1.0s forwards; /* for less modern browsers */
animation: bubble 1.0s forwards;
If you are using more animation attributes the shorthand is:
animation: bubble 2s linear 0.5s 1 normal forwards;
This gives:
bubble animation name
2s duration
linear timing-function
0.5s delay
1 iteration-count (can be 'infinite')
normal direction
forwards fill-mode (set 'backwards' if you want to have compatibility to use the end position as the final state[this is to support browsers that has animations turned off]{and to answer only the title, and not your specific case})
Available timing-functions:
ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end
Available directions
normal | reverse | alternate | alternate-reverse
IF NOT USING THE SHORT HAND VERSION: Make sure the animation-fill-mode: forwards is AFTER the animation declaration or it will not work...
animation-fill-mode: forwards;
animation-name: appear;
animation-duration: 1s;
animation-delay: 1s;
vs
animation-name: appear;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-delay: 1s;
Use
animation-fill-mode: forwards;
animation-fill-mode: forwards;
The element will retain the style values that is set by the last keyframe (depends on animation-direction and animation-iteration-count).
Note: The #keyframes rule is not supported in Internet Explorer 9 and earlier versions.
Working example
div {
width: 100px;
height: 100px;
background: red;
position :relative;
-webkit-animation: mymove 3ss forwards; /* Safari 4.0 - 8.0 */
animation: bubble 3s forwards;
/* animation-name: bubble;
animation-duration: 3s;
animation-fill-mode: forwards; */
}
/* Safari */
#-webkit-keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
/* Standard syntax */
#keyframes bubble {
0% { transform:scale(0.5); opacity:0.0; left:0}
50% { transform:scale(1.2); opacity:0.5; left:100px}
100% { transform:scale(1.0); opacity:1.0; left:200px}
}
<h1>The keyframes </h1>
<div></div>
I had an issue using forwards: at least in Chrome, even after the animation ended, the renderer was still sucking up graphics resources, making the application less responsive.
An approach that does not cause this trouble is by using an EventListener.
CSS animations emit events, so you can use the animationend event to intervene when the animation ends.
CSS
.fade_in {
animation: fadeIn 2s;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
JavaScript
const element = document.getElementById("element-to-be-animated");
element.addEventListener("animationend", () => {
// Set your final state here. For example:
element.style["opacity"] = 1;
}, { once: true });
The option once: true tells the engine to remove the event listener after its execution, leaving your application fresh and clean.
I have created a JSFiddle to show how it works.