CSS animation suddenly ends - javascript

I created a spinner animation. On click on spinner, JS adds class "loading" and it starts rotating. But if I remove this class it returns to the previous position without animation.
I tried to use this:
animation-fill-mode: forwards;, but result was the same.
There is my CSS:
.loading {
animation: spin 1s linear infinite 0s forwards;
}
#keyframes spin{
from{
transform: rotate(0deg)
}
to{
transform: rotate(360deg)
}
}
And HTML:
<i class="material-icons refresh-icon" onclick="$(this).toggleClass('loading');">refresh</i>

Thanks for your suggestions. I did it using JS and animationiteration event.
HTML:
<div class="spinner">
<i class="material-icons refresh-icon" onclick="spinner(this)">refresh</i>
</div>
JS:
const spinner = el => {
if($(el).hasClass('lock')) return;
if($(el).hasClass('loading')){
$(el).addClass('lock').one('animationiteration webkitAnimationIteration', function() {
$(el).removeClass('loading').removeClass('lock');
});
}else{
$(el).addClass('loading');
}
}
Link to codepan: https://codepen.io/nenazarko/pen/zYGPoZy

Related

Is there a better way to add/remove classes for menu with Javascript

This is what I have so far..
icons.addEventListener('click', (e)=>{
if(e.target.className==="skate"){
navigation.classList.remove('slideIn');
navigation.classList.add('slideOut');
skateboard.classList.add('skateOff');
x.classList.add('xslide');
}else{
navigation.classList.remove('slideOut');
navigation.classList.add('slideIn');
skateboard.classList.remove('skateOff');
x.classList.remove('xslide');
}
})
#keyframes skateOff{
0%{
transform:rotate(0);
}
50%{
transform:rotate(49deg);
}
100%{
transform: translateX(-300px);
}
}
.skateOff{
animation: skateOff ease-in 1s forwards;
}
.x{
visibility: hidden;
}
.xslide{
animation:slideOut .8s ease 2s forwards;
}
.menu{
visibility: hidden;
color:black;
width:10em;
background-color:white;
border-radius: 4px;
font-family: 'Raleway';
background: linear-gradient(to right,
rgba(249,107,142,1),
rgba(218,103,230,1),
rgba(130,125,253,1));
}
.slideOut{
animation: slideOut 1s forwards 1.2s;
}
#keyframes slideOut{
0%{
transform: translateX(-50%);
}
100%{
visibility: visible;
transform: translateX(0);
}
}
.slideIn{
animation: slideIn 2s ease forwards;
}
#keyframes slideIn{
0%{
visibility: visible;
transform: translateX(0);
}
100%{
transform: translateX(-150%);
}
}
The functionality of the JS is this,
when "skateboard" is clicked, it animates out, to the left and is no longer visible (the skateOff keyframes makes that happen, and i added a class that has that animation implemented also called ".skateOff")
(would it be better to not have a separate class and just add
skateboard.style.animation="animation: skateOff ease-in 1s forwards"?)
..anyway
then after "skateboard" animates out the "navigation"(which is a sidebar menu) adds the "slideOut" class which makes it slide out from the left, along with this the "X" to close the menu slide out, when that is clicked the "navigation"'s class of "slideOut" gets removed and the class of "slideIn" gets added.
This way of doing things seems inefficient, and like a lot of code, I was wondering if there's a simpler way of doing this? Toggling maybe? I've looked into toggling but i'm not sure it will work since the "navigation" element's initial state doesn't have the "slideIn" or "slideOut" class.
ANY tips will be greatly appreciated, thank you for reading and have a great day.
first of all, welcome on Stack Overflow :)
Your code may benefit from classList.toggle (https://developer.mozilla.org/pl/docs/Web/API/Element/classList).
You can have conditional statements there, meaning classList.toggle("string", boolean), like this:
icons.addEventListener('click', (e)=> {
const isSkate = e.target.className === "skate"; // this could also be altered using classList.contains()
navigation.classList.toggle('slideIn', !isSkate);
navigation.classList.toggle('slideOut', isSkate);
skateboard.classList.toggle('skateOff', isSkate);
x.classList.toggle('xslide', isSkate);
});
A little PoC can be found here: https://codepen.io/tomekbuszewski/pen/XyNzqG
If you need more help, please post your code to CodePen or JSFiddle, it would be easier to discuss then.

have jquery add(or trigger?) an animation

So I have a graph that is filled out through a nice animation. This happens because every bar in the graph has the css attribute
animation: slide-left 0.9s ease-in-out 1s both;
The animation looks like this:
#keyframes slide-left {
0% {
-webkit-transform: translateX(-200%);
}
70% {
-webkit-transform: translateX(2%);
}
100% {
-webkit-transform: translateX(0);
}
}
Now, I'm not very good at javascript but I'd like this to happen on the click of a button (and have the graph hidden until the button is clicked) instead of when the page loads.
Now I've removed the animation-attribute from the css-selector and added translateX(-200%);
Realized that if I add animation: slide-left 0.9s ease-in-out 1s both; through inspect element, exactly what I want happens.
So I found a "solution" that looks like this:
$("#button").on('click', show_function);
function show_function() {
$(".graph").fadeIn("slow");
$('<style>.bar-container>* { animation: slide-left 1s ease-in-out 1s both; }</style>').prependTo('body');
}
This feels "clunky" and it takes almost a second to load. So I was wondering what a better way to have a function trigger the animation in javascript/JQuery would be?
Your best answer is likely to be have the animation sequence in a class, and use jQuery to add the class. E.g.
CSS
#keyframes slide-left {
0% {
-webkit-transform: translateX(-200%);
}
70% {
-webkit-transform: translateX(2%);
}
100% {
-webkit-transform: translateX(0);
}
}
.slide-it {
animation: slide-left 0.9s ease-in-out 1s both;
}
And then JS
$("#button").on('click', show_function);
function show_function() {
$(".graph").fadeIn("slow");
$('.bar-container').addClass('slide-it');
}

Fade In and Out on Button Click

The CSS styling for this fade in and out animation seems fine, but it is not reusable with javascript. Once the function performs once, it can not be triggered by button onClick again, what is the way around this?
//removeClass
//addClass
.elementToFadeInAndOut {
width:200px;
height: 200px;
background: red;
-webkit-animation: fadeinout 4s linear forwards;
animation: fadeinout 4s linear forwards;
opacity: 0;
}
#-webkit-keyframes fadeinout {
50% { opacity: 1; }
}
#keyframes fadeinout {
50% { opacity: 1; }
}
<button onClick="animationfunction()">Button</button>
<div id="icon" class="elementToFadeInAndOut"></div>
You only need to have the button click add the class membership, wait until the animation is complete and then remove the class.
var div = document.querySelector(".fade");
var btn = document.querySelector(".fadeButton");
btn.addEventListener("click", function(){
div.classList.add("elementToFadeInAndOut");
// Wait until the animation is over and then remove the class, so that
// the next click can re-add it.
setTimeout(function(){div.classList.remove("elementToFadeInAndOut");}, 4000);
});
.fade{
width:200px;
height: 200px;
background: red;
opacity:0;
}
.elementToFadeInAndOut {
animation: fadeInOut 4s linear forwards;
}
#keyframes fadeInOut {
0% { opacity:0; }
50% { opacity:1; }
100% { opacity:0; }
}
<button class="fadeButton">Button</button>
<div class="fade"></div>
The best way is to use jQuery for functions
here is the code for fade in and out effect for toggle button.
you can adjust the time by changing that (1000) in jQuery Thank you
$(document).ready(function(){
$('button.btn').click(function(){
$("div.elementToFadeInAndOut").fadeOut(1000);
$("div.elementToFadeInAndOut").fadeIn(1000);
});
});
.elementToFadeInAndOut {
width:200px;
height: 200px;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<button class="btn">Button</button>
<div class="elementToFadeInAndOut"></div>

How to make simple fade effect or slow animation onmouseover with jQuery

Like in the topic. My code looks like:
$('li a').mouseover(function () {
var rhomboidImg = $(this).data('rhomboid-img');
$('#img-nav-rhomboid').css('background', 'url(' + rhomboidImg + ') no-repeat ');
$('#img-nav-rhomboid img').delay(2000).fadeIn();
});
And here is html:
<nav class="menu-closed">
<div id="img-nav-rhomboid" class="nav-rhomboid"></div>
<ul class="menu-list">
<li class="menu-accent-border"><img src="img/menu-mrowka.jpg" alt="Materiały Budowlane"/><li>
<li>Mrówka Wszystko dla domu</li>
<li>Sklep instalacyjno-metalowy</li>
<li class="menu-accent-border2"><img src="img/menu-psb.jpg" alt="Materiały Budowlane"/><li>
<li>Magazyn materiałów budowlanych Opalenica</li>
<li>Magazyn materiałów budowlanych Nowy Tomyśl</li>
<li>Magazyn materiałów budowlanych Grodzisk Wlkp.</li>
<li class="menu-accent-border3">Centrum ogrodnicze OPALFLORA</li>
<li>Betoniarnia</li>
<li>Uścięcice</li>
</ul>
</nav>
When I hover on li element it should change the picture, but with some animation.
If you're only trying to create a fade-in animation on hover you might as well want to use CSS
.rhomboid-img{
opacity: 0;
}
.rhomboid-img:hover{
opacity: 1;
transition: 2s all ease-in-out;
}
Since you tagged css, I am going to give you some CSS code that will work for this:
#keyframes fadeIn {
0% {
opacity: 0
}
to {
opacity: 1
}
}
.fadeIn {
animation-name: fadeIn
}
This above is courtesy of https://github.com/daneden/animate.css
.rhomboid-img {
-webkit-transition-delay: 2s;
transition-delay: 2s;
This above will delay the fade in for your desired 2000 or two seconds. Just make sure you use both .fadeIn and .rhomboid-img classes.

CSS Transition and animation disappear after the starting animation finished

Hi,
I have a problem on CSS animation and transition.
$(document).ready(function(){
$(".d1").click(function(e){
$(".d2").css("animation-direction", "reverse");
$(".d3").css("animation-direction", "reverse");
});
$(".d2").click(function(e){
$(".d1").css("animation-name", "none").css("opacity", 0);
$(".d3").css("animation-name", "none").css("opacity", 0);
});
$(".d3").click(function(e){
$(".d1").css("animation-name", "none").fadeOut("slow");
$(".d2").css("animation-name", "none").fadeOut("slow");
});
});
#keyframes inseq {
100% { opacity: 1; }
}
.d1, .d2, .d3 {
opacity: 0;
transition: all 2s;
animation: inseq 3s ease 1s forwards;
}
.d2 {
animation-delay: 1.3s
}
.d3 {
animation-delay: 1.6s
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="d1">1</div>
<div class="d2">2</div>
<div class="d3">3</div>
https://jsfiddle.net/v7mepwmg/2/
I have a starting-fade-in animation on a series of elements, and then using jquery click event to trigger fadeout; I have tried 3 methods (in example they are .d1 .d2 and .d3 click event) to achieve so, but none of them can do so while the animation finished.....
P.S. If the animation has not finished yet, they work well...
Do I miss anything ?? Thanks!
Updated this a little.
It has something to do with the opacity=0 set on the div elements and the use of animation-direction:reverse. Tough to explain. Basically it jumps to the initial key-frame without any animation. So I've created another set of keyframes for out animation instead of using animation-direction:reverse.
#keyframes in {
from {opacity: 0;}
to {opacity: 1;}
}
#keyframes out {
from {opacity: 1;}
to {opacity: 0;}
}
.d1,.d2,.d3 {
opacity: 0;
animation: in 3s ease 1s forwards 1;
}
.d2 {animation-delay: 1.3s}
.d3 {animation-delay: 1.6s}
And then used this to add the second animation and change the initial opacity.
$(document).ready(function() {
$('div').click(function(e) {
var selected = $(this).attr('class');
$('div').not("." + selected).css({
'opacity': '1',
'animation' : 'out 3s ease forwards 1'
}).delay('3000').fadeOut('0');
});
});
Here's the updated Fiddle.
https://jsfiddle.net/thelessergeek/0pwan8qm/

Categories