Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reset CSS transition once it played

I have a plus sign that appears if you push the space button. But now it appears once. Can you help me to make it appear every time I press the space button? Here is my Code Pen.

import './style.scss';

let counter = 0;

document.addEventListener('keydown', ({ keyCode }) => {
  const increment = document.getElementsByClassName('increment')[0];
  if (keyCode === 32) {
    counter++;
    document.getElementsByClassName('counter')[0].innerText = counter;

    increment.classList.remove('hidden');
    increment.classList.add('move-increment');
  }
});
.container {
   /* ... */

  .counter {
    background-color: gray;
    color: white;
    border-radius: 10px;
    padding: 10px;
  }

  .move-increment {
    margin-top: -20px;
    opacity: 0;
  }

  .hidden {
    visibility: hidden;
  }

  .increment {
    position: absolute;
    margin-left: -33px;
    z-index: 1;
    transition: margin-top 1s cubic-bezier(0, 0.5, 0.5, 1),
      opacity 1s ease-in-out;
  }
}
like image 315
Ярослав Терещук Avatar asked Jul 12 '20 16:07

Ярослав Терещук


People also ask

How do you reset an animation in CSS?

To restart animation in CSS3 and JavaScript, we can get the offsetHeight property to trigger reflow. function resetAnimation() { const el = document. getElementById("animated"); el. style.

How do you repeat an animation in CSS?

The animation-iteration-count property in CSS is used to specify the number of times the animation will be repeated. It can specify as infinite to repeat the animation indefinitely.

How do you stop a transition in CSS?

To trigger an element's transition, toggle a class name on that element that triggers it. To pause an element's transition, use getComputedStyle and getPropertyValue at the point in the transition you want to pause it. Then set those CSS properties of that element equal to those values you just got.

Can you have multiple transitions CSS?

You can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.


2 Answers

Although I consider @ikiK's answer as the correct answer because the question was specifically about using CSS transitions, I would like to share a different approach. I think the goal of the 'plus' icon is to be displayed each time the counter increments. But when the counter increments while the transition of the previous increment is still playing it is impossible to display a second 'plus' symbol.

My suggestion would be to use some jQuery and, on each increment, append a new li item to an unordered list that is positioned right on top of the counter. Animate that li, fading it out to the top. And then use the callback function of animate() to remove the li element from the DOM once it has faded out of view.

let counter = 1;
$(document).on( 'keypress',function(e) {
    if( e.which == 32 ) {
        $('.counter').text(counter++);
        let increment = $('<li><span class="increment">+</span></li>');
        $('#increments').append(increment);
        increment.animate({
            opacity: 0,
            top: '-=30px'
        }, 500, function() {
            increment.remove();
        });
    }
});
.container {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 40px;
    font-weight: bold;
    display: flex;
    height: 500px;
    align-items: top;
    justify-content: center;
    position: relative;
  overflow: hidden;
  height: 100px;
}

.counter {
    background-color: gray;
    color: white;
    border-radius: 10px;
    padding: 10px;
}

#increments {
    padding: 0px;
    z-index: 1;
    float: left;
    margin-left: -33px;
    list-style: none;
}

#increments li {
    position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
    <p>Counter: <span class="counter">0</span></p>
    <ul id="increments"></ul>
</div>
like image 55
Terminator-Barbapapa Avatar answered Oct 31 '22 13:10

Terminator-Barbapapa


Remove added .move-increment and add again removed hidden classes with slight delay, this will re-apply your transition: margin-top (read in provided links why delay):

    setTimeout(function() {increment.classList.add('hidden');
    increment.classList.remove('move-increment');}, 600);   

Solution (changed key-code to arrow up: ↑ ):

let counter = 0;

document.addEventListener('keydown', ({
    keyCode
  }) =>

  {
    const increment = document.getElementsByClassName('increment')[0];
    if (keyCode === 38) {
      counter++;
      document.getElementsByClassName('counter')[0].innerText = counter;

      increment.classList.remove('hidden');
      increment.classList.add('move-increment');

      setTimeout(function() {
        increment.classList.add('hidden');
        increment.classList.remove('move-increment');
      }, 600);
    }
  });
.container {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 40px;
  font-weight: bold;
  display: flex;
  height: 100px;
  align-items: center;
  justify-content: center;
}

.counter {
  background-color: gray;
  color: white;
  border-radius: 10px;
  padding: 10px;
}

.move-increment {
  margin-top: -20px;
  opacity: 0;
}

.hidden {
  visibility: hidden;
}

.increment {
  position: absolute;
  margin-left: -33px;
  z-index: 1;
  transition: margin-top 1s cubic-bezier(0, 0.5, 0.5, 1), opacity 1s ease-in-out;
}
<div class="container">
  <div>
    Counter: <span class="counter">0</span>
    <span class="increment hidden">+</span>
  </div>
</div>

But however, this is not working perfectly when pressing key too fast. Try changing setTimeout duration and see what suits your need.

In links provided you have examples how to reset animation (not transition) all together and would solve this fast key press issues.

Read about this here, few really useful info's:

Restart CSS Animation

Controlling CSS Animations and Transitions with JavaScript

like image 22
ikiK Avatar answered Oct 31 '22 11:10

ikiK