Moving element on screen and back with keyframes - javascript

Provided I have following code:
<div class="leftBox">
<div class="mainNode"></div>
</div>
<script type="text/javascript">
$('.mainNode').click(function() {
var element = $('.mainNode');
if (!element.hasClass('show')) {
element.removeClass('hide');
element.addClass('show');
} else {
element.removeClass('show');
element.addClass('hide');
}
})
</script>
and in CSS:
.mainNode {
width: 160px;
height: 160px;
border-radius: 50%;
background-color: red;
position :relative;
}
.show {
-webkit-animation: mymove 1s forwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s forwards;
}
.hide {
-webkit-animation: mymove 1s reverse; /* Safari 4.0 - 8.0 */
animation: mymove 1s reverse;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
/* Standard syntax */
#keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
What I'm looking for is that my circle moves to the bottom when I click it using the keyframes (I will have more of them in the future).
After the first click the circle should stay at the bottom, this is happening already with the code above.
However, when I reclick the circle, I want it to do the same animation in reverse and return to the original position. Also allowing me to reclick it after to move it back down using the same animation... This is currently not working. It moves down and the jumps to the top and the bottom without the animation.
Any help would be appreciated.
Here be my example

Please try this. I try my best. Animation work top to bottom and bottom to top every time.
$('.mainNode').click(function() {
var element = $('.mainNode');
if (!element.hasClass('show')) {
element.removeClass('hide');
element.addClass('show');
element.before( element.clone(true)).remove();
} else {
element.removeClass('show');
element.addClass('hide');
element.before( element.clone(true)).remove();
}
})
.mainNode {
width: 160px;
height: 160px;
border-radius: 50%;
background-color: red;
position :relative;
}
.show {
-webkit-animation: mymove 1s forwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s forwards;
}
.hide {
-webkit-animation: mymove1 1s forwards; /* Safari 4.0 - 8.0 */
animation: mymove1 1s forwards;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
/* Standard syntax */
#keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove1 {
from {top: 200px;}
to {top: 0px;}
}
/* Standard syntax */
#keyframes mymove1 {
from {top: 200px;}
to {top: 0px;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="leftBox">
<div class="mainNode"></div>
</div>

Use backwords instead of reverse it will work for you.
.hide {
-webkit-animation: mymove 1s backwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s backwards;
animation-delay: .2s;
}

You need to change two things to make this work:
.hide {
-webkit-animation: mymove 1s reverse forwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s reverse forwards;
animation-delay: .2s;
}
Use animation-direction reverse, but animation-fill-mode forwards. This way, the animation will start from the end, and stay at the last keyframe (which is back at the top).
But there is an additional problem: As soon as the show class is removed, it jumps back to top, since the animation no longer applies. To prevent this, you can add animation-name: mymove to your .mainNode.
.mainNode {
animation-name: mymove;
// Other properties...
}
See it in action here: https://codepen.io/anon/pen/jLgrjW

Related

I want to do an animation, but just one time, not to be on a loop [duplicate]

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.

Smooth animation start

I've got an animation that just moves from top to the bottom.
0 - top
25 - middle
50 - bottom
75 - middle
100 - top
I've made it endless using javascript but every time it stops and starts again it blinks (disappears and appears for 1 second).
Is there a way to make this action smooth without blinking at start?
Without seeing your code it's difficult to know, but I'd imagine it may have something to do with the way you've set up your #keyframes. For an infinite looping animation with no glitch, try something like this:
HTML:
div {
width: 100px;
height: 100px;
background: red;
position: relative;
-webkit-animation: mymove 2s infinite; /* Safari 4.0 - 8.0 */
animation: mymove 2s infinite;
}
CSS:
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove {
0% {top: 0px;}
50% {top: 100px;}
100% {top: 0px;}
}
/* Standard syntax */
#keyframes mymove {
0% {top: 0px;}
50% {top: 100px;}
100% {top: 0px;}
}
Hope this helps 👍

Make Color of an Element Pulse Continuously With Angular

I am trying to make the color of a button pulse from its current color, say, #ed8c55, to pure white and back to the original color with the entire cycle taking about 2-3 seconds. How could I do that?
In particular, I see that there are a couple of problems here. One is to make the timer and attach some variable's increment to the value of the color. The second problem is the actual color itself. How would one go about continuously changing a hex color towards white and back using a loop of some sort?
I have the following timer implemented that counts seconds. I could easily modify it to count milliseconds or something like that.
var mytimeout = null; // the current timeoutID
$scope.counter = 0;
// actual timer method, counts up every second
$scope.onTimeout = function() {
$scope.counter++;
mytimeout = $timeout($scope.onTimeout, 1000);
};
Any help is appreciated.
I know you want an animation via AngularJS but I dont think thats the right tool for the job as its easily achieved via CSS alone. I'd really advise you to do it like so;
EDIT ------------------
After your comments of dynamically adding a background colour that will then pulse the best way is to inline style the colour via angular and css keyframe the animation.
CSS --
#-webkit-keyframes pulse {
25% { background-color: #FFF; }
}
#-moz-keyframes pulse {
25% { background-color: #FFF; }
}
#-o-keyframes pulse {
25% { background-color: #FFF; }
}
#keyframes pulse {
25% { background-color: #FFF; } // changed to 25% to stop the sudden change to white
}
.element {
transition: background-color 3s;
width: 50px;
height: 50px;
-webkit-animation: pulse 3s infinite; /* Safari 4+ */
-moz-animation: pulse 3s infinite; /* Fx 5+ */
-o-animation: pulse 3s infinite; /* Opera 12+ */
animation: pulse 3s infinite; /* IE 10+, Fx 29+ */
}
HTML -
<div style="background-color: #ed8c55;" class="element"></div>
View my codepen here
/ EDIT ------------------
OG Answer ---
#-webkit-keyframes pulse {
0% { background-color: #ed8c55; }
50% { background-color: #FFF; }
100% { background-color: #ed8c55; }
}
#-moz-keyframes pulse {
0% { background-color: #ed8c55; }
50% { background-color: #FFF; }
100% { background-color: #ed8c55; }
}
#-o-keyframes pulse {
0% { background-color: #ed8c55; }
50% { background-color: #FFF; }
100% { background-color: #ed8c55; }
}
#keyframes pulse {
0% { background-color: #ed8c55; }
50% { background-color: #FFF; }
100% { background-color: #ed8c55; }
}
.element {
width: 50px;
height: 50px;
background: #ed8c55;
-webkit-animation: pulse 3s infinite; /* Safari 4+ */
-moz-animation: pulse 3s infinite; /* Fx 5+ */
-o-animation: pulse 3s infinite; /* Opera 12+ */
animation: pulse 3s infinite; /* IE 10+, Fx 29+ */
}
And that will continuously loop between the two colours.
You can view my code pen on it here.

CSS3 Keyframe Animations: End and stay on the last frame

I've run into some difficulty trying to play a CSS3 keyframe animation and have the relevant element stick at the last frame after the animation has completed. To my understanding, the property that I have to set for this to work should be animation-fill-mode, which should have the value of forwards; this doesn't do anything.
.animatedSprite {
.animation-name: sprite;
.animation-duration: .5s;
.animation-iteration-count: 1;
.animation-direction: normal;
.animation-timing-function: steps(3);
.animation-fill-mode: forwards;
//Vendor prefixes... }
This will just play the animation once and then go back to the first frame. I found an example of keyframe animations at JSFiddle ( http://jsfiddle.net/simurai/CGmCe/ ), and changing the fill mode to forwards and setting the iteration count to 1 wouldn't do anything there, either.
Any help would be greatly appreciated.
animation-fill-mode:forwards is the correct property to use. Is does not seem to work because the sprite image background has a default background-repeat:repeat, so the last frame you think you are seeing is actually the first frame of the repeated background image.
If you set
background: url("http://files.simurai.com/misc/sprite.png") no-repeat
animation: play .8s steps(10) forwards;
#keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
and run the demo the final frame is now blank - so forwards is doing what it should do. The second part of the solution is to change the final to and steps CSS properties to position the background correctly. So we really need the background to stop at -450px and use 9 steps.
-webkit-animation: play .8s steps(9) forwards;
#keyframes play {
from { background-position: 0; }
to { background-position: -450px; }
}
See demo - I only fixed the Chrome properties. Also here is the sample image in case the original disappears.
.hi {
width: 50px;
height: 72px;
background: url("http://i.stack.imgur.com/ilKfd.png") no-repeat;
-webkit-animation: play .8s steps(9) forwards;
-moz-animation: play .8s steps(10) infinite;
-ms-animation: play .8s steps(10) infinite;
-o-animation: play .8s steps(10) infinite;
animation: play .8s steps(9) forwards;
}
#-webkit-keyframes play {
from { background-position: 0px; }
to { background-position: -450px; }
}
#-moz-keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
#-ms-keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
#-o-keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
#keyframes play {
from { background-position: 0px; }
to { background-position: -450px; }
}
<div class="hi"></div>
Change 'infinite' to '1' in the css, this fixes it for me
just add
animation: mymove .8s forwards;
here 'mymove' is name of my keyframe
example:
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: red;
position: relative;
animation: mymove .8s forwards;
}
#keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
</style>
</head>
<body>
<h1>The #keyframes Rule</h1>
<div></div>
</body>
</html>
The following code will make the transition stay on the last frame:
-webkit-timing-function:ease;
-webkit-iteration-count:1;

How can i make the final state of an animation persist?

I animate the width of an div from 0 to 100%, and after the animation is done i want the final result to persist. Here is what i have until now:
<style>
#element {
background: yellow;
bottom:0;
height:70px;
animation:myfirst 5s;
-moz-animation:myfirst 5s; /* Firefox */
-webkit-animation:myfirst 5s; /* Safari and Chrome */
-o-animation:myfirst 5s;}
#keyframes myfirst {
from {width:0px;}
to {width:100%;}
}
#-moz-keyframes myfirst /* Firefox */ {
from {width:0px;}
to {width:100%;}
}
#-webkit-keyframes myfirst /* Safari and Chrome */ {
from {width:0px;}
to {width:100%;}
}
#-o-keyframes myfirst /* Opera */ {
from {width:0px;}
to {width:100%;}
}
Is there a CSS way or JS to do that?
Use the forwards or both properties:
-webkit-animation:myfirst 5s forwards;
Then the animation will stop at 100% and persist.

Categories