Add CSS swap animation in div on click only once

I have a CSS map PIN that has some CSS3 animations, here it is: '

https://jsfiddle.net/xg7xfzeq/

body { background: #e6e6e6; } .pin { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; background: #00cae9; position: absolute; transform: rotate(-45deg); left: 50%; top: 50%; margin: -20px 0 0 -20px; } .pin:after { content: ""; width: 14px; height: 14px; margin: 8px 0 0 8px; background: #e6e6e6; position: absolute; border-radius: 50%; } .bounce { animation-name: bounce; animation-fill-mode: both; animation-duration: 1s; } .pulse { background: #d6d4d4; border-radius: 50%; height: 14px; width: 14px; position: absolute; left: 50%; top: 50%; margin: 11px 0px 0px -12px; transform: rotateX(55deg); z-index: -2; } .pulse:after { content: ""; border-radius: 50%; height: 40px; width: 40px; position: absolute; margin: -13px 0 0 -13px; animation: pulsate 1s ease-out; animation-iteration-count: infinite; opacity: 0; box-shadow: 0 0 1px 2px #00cae9; animation-delay: 1.1s; } @keyframes pulsate { 0% { transform: scale(0.1, 0.1); opacity: 0; } 50% { opacity: 1; } 100% { transform: scale(1.2, 1.2); opacity: 0; } } @keyframes bounce { 0% { opacity: 0; transform: translateY(-2000px) rotate(-45deg); } 60% { opacity: 1; transform: translateY(30px) rotate(-45deg); } 80% { transform: translateY(-10px) rotate(-45deg); } 100% { transform: translateY(0) rotate(-45deg); } } .myBounceDiv { -moz-animation:bounce .40s linear; -webkit-animation:bounce .40s linear; } @-moz-keyframes bounce { 0%{ -moz-transform:scale(0); opacity:0;} 50%{ -moz-transform:scale(1.3); opacity:0.4; } 75%{ -moz-transform:scale(0.9); opacity:0.7;} 100%{ -moz-transform:scale(1); opacity:1;} } @-webkit-keyframes bounce { 0%{ -webkit-transform:scale(0); opacity:0;} 50%{ -webkit-transform:scale(1.3); opacity:0.4;} 75%{ -webkit-transform:scale(0.9); opacity:0.7;} 100%{ -webkit-transform:scale(1); opacity:1;} } 

and its HTML

 <div class='myBounceDiv'> <div class='pin bounce'></div> <div class='pulse'></div> </div> 

Well, I want to add a css3 bounce animation to a click, I found some solutions for it, such as changing the CSS style when we click on its div using javascript. Although it’s possible, but when I change my CSS class, it will start to refuse every time forever. How to make animation only once? One way can start the timer and after 1000 ms change its css class to the first class, but there is another problem: my div class has a different animation (when it appears on the first page, it falls from top to bottom), so if I change its css class to bounce animation and change it back to the original appearance animation animation again and that is not what i need. Is there a way to achieve what I need using pure javascript and CSS? Actually, I need to do something like this http://dynamicsjs.com/examples/pin.html but its animation appears when I click on CSS.

+5
source share
2 answers

Instead of changing CSS classes to bounce animations and returning to the original, you can instead add (by click) and delete (after 1s) the classes either pin or myBounceDiv . It should be noted that after the animation is complete, you will also need to remove the bounce class.

It will look something like this:

 const pinEl = document.querySelector('.pin'); setTimeout(() => pinEl.classList.remove('bounce'), 1000); function removeMiniBounce() { pinEl.classList.remove("miniBounce"); } pinEl.onclick = () => { pinEl.classList.add("miniBounce"); setTimeout(removeMiniBounce, 1000); } 

And your CSS will be:

 @keyframes miniBounce { 0%{ -webkit-transform:translateY(0px) rotate(-45deg);} 30%{ -webkit-transform:translateY(-20px) rotate(-45deg);} 60%{ -webkit-transform:translateY(0px) rotate(-45deg);} 70%{ -webkit-transform:translateY(-5px) rotate(-45deg);} 100%{ -webkit-transform:translateY(0) rotate(-45deg);} } .miniBounce { animation: miniBounce 0.4s ease-in-out; } 
+1
source

As I understand it, you mean this:

  • In the first version, the pulse effect and the rebound effect are triggered only once.
  • In the second version, the impulse effect always starts as a real version, but the rebound effect is triggered only with a mouse click

First version

 element = document.getElementById("marker"); element.addEventListener("click", function(e) { e.preventDefault; // -> removing the class element.classList.remove("bounce"); // -> triggering reflow /* The actual magic */ // without this it wouldn't work. Try uncommenting the line and the transition won't be retriggered. element.offsetWidth = element.offsetWidth; // -> and re-adding the class element.classList.add("bounce"); }, false); 
 body { background: #e6e6e6; } .pin { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; background: #00cae9; position: absolute; transform: rotate(-45deg); left: 50%; top: 50%; margin: -20px 0 0 -20px; } .pin:after { content: ""; width: 14px; height: 14px; margin: 8px 0 0 8px; background: #e6e6e6; position: absolute; border-radius: 50%; } .bounce { animation-name: bounce; animation-fill-mode: both; animation-duration: 0.9s; } .pulse { background: #d6d4d4; border-radius: 50%; height: 14px; width: 14px; position: absolute; left: 50%; top: 50%; margin: 11px 0px 0px -12px; transform: rotateX(55deg); z-index: -2; } .bounce+.pulse:after { content: ""; border-radius: 50%; height: 40px; width: 40px; position: absolute; margin: -13px 0 0 -13px; animation: pulsate 1s ease-out; opacity: 0; box-shadow: 0 0 1px 2px #00cae9; animation-delay: 0.1s; -webkit-animation-iteration-count: 1; animation-iteration-count: 1; } @keyframes pulsate { 0%, 100% { transform: scale(0.1, 0.1); opacity: 0; } 50% { opacity: 1; } 100% { transform: scale(1.2, 1.2); opacity: 0; } } @keyframes bounce { 0% { opacity: 0; transform: translateY(-1000px) rotate(-45deg); } 60% { opacity: 1; transform: translateY(30px) rotate(-45deg); } 80% { transform: translateY(-10px) rotate(-45deg); } 100% { transform: translateY(0) rotate(-45deg); } } .myBounceDiv { -moz-animation:bounce .40s linear; -webkit-animation:bounce .40s linear; } @-moz-keyframes bounce { 0%{ -moz-transform:scale(0); opacity:0;} 50%{ -moz-transform:scale(1.3); opacity:0.4; } 75%{ -moz-transform:scale(0.9); opacity:0.7;} 100%{ -moz-transform:scale(1); opacity:1;} } @-webkit-keyframes bounce { 0%{ -webkit-transform:scale(0); opacity:0;} 50%{ -webkit-transform:scale(1.3); opacity:0.4;} 75%{ -webkit-transform:scale(0.9); opacity:0.7;} 100%{ -webkit-transform:scale(1); opacity:1;} } 
 <div class='myBounceDiv'> <div id="marker" class='pin'></div> <div class='pulse'></div> </div> 

Second version

 /* Reference: https://css-tricks.com/restart-css-animation/ */ element = document.getElementById("marker"); element.addEventListener("click", function(e) { e.preventDefault; // -> removing the class element.classList.remove("bounce"); // -> triggering reflow /* The actual magic */ // without this it wouldn't work. Try uncommenting the line and the transition won't be retriggered. element.offsetWidth = element.offsetWidth; // -> and re-adding the class element.classList.add("bounce"); }, false); 
 body { background: #e6e6e6; } .pin { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; background: #00cae9; position: absolute; transform: rotate(-45deg); left: 50%; top: 50%; margin: -20px 0 0 -20px; } .pin:after { content: ""; width: 14px; height: 14px; margin: 8px 0 0 8px; background: #e6e6e6; position: absolute; border-radius: 50%; } .bounce { animation-name: bounce; animation-fill-mode: both; animation-duration: 0.9s; } .pulse { background: #d6d4d4; border-radius: 50%; height: 14px; width: 14px; position: absolute; left: 50%; top: 50%; margin: 11px 0px 0px -12px; transform: rotateX(55deg); z-index: -2; } .pulse:after { content: ""; border-radius: 50%; height: 40px; width: 40px; position: absolute; margin: -13px 0 0 -13px; animation: pulsate 1s ease-out; animation-iteration-count: infinite; opacity: 0; box-shadow: 0 0 1px 2px #00cae9; animation-delay: 0.1s; } @keyframes pulsate { 0%, 100% { transform: scale(0.1, 0.1); opacity: 0; } 50% { opacity: 1; } 100% { transform: scale(1.2, 1.2); opacity: 0; } } @keyframes bounce { 0% { opacity: 0; transform: translateY(-1000px) rotate(-45deg); } 60% { opacity: 1; transform: translateY(30px) rotate(-45deg); } 80% { transform: translateY(-10px) rotate(-45deg); } 100% { transform: translateY(0) rotate(-45deg); } } .myBounceDiv { -moz-animation:bounce .40s linear; -webkit-animation:bounce .40s linear; } @-moz-keyframes bounce { 0%{ -moz-transform:scale(0); opacity:0;} 50%{ -moz-transform:scale(1.3); opacity:0.4; } 75%{ -moz-transform:scale(0.9); opacity:0.7;} 100%{ -moz-transform:scale(1); opacity:1;} } @-webkit-keyframes bounce { 0%{ -webkit-transform:scale(0); opacity:0;} 50%{ -webkit-transform:scale(1.3); opacity:0.4;} 75%{ -webkit-transform:scale(0.9); opacity:0.7;} 100%{ -webkit-transform:scale(1); opacity:1;} } 
 <div class='myBounceDiv'> <div id="marker" class='pin'></div> <div class='pulse'></div> </div> 

UPDATE

 /* Reference: https://css-tricks.com/restart-css-animation/ */ element = document.getElementById("marker"); setTimeout(function() { element.classList.remove("bounce"); }, 1000); element.addEventListener("click", function(e) { e.preventDefault; // -> removing the class element.classList.remove("drop"); // -> triggering reflow /* The actual magic */ // without this it wouldn't work. Try uncommenting the line and the transition won't be retriggered. element.offsetWidth = element.offsetWidth; // -> and re-adding the class element.classList.add("drop"); }, false); 
 body { background: #e6e6e6; } .pin { width: 30px; height: 30px; border-radius: 50% 50% 50% 0; background: #00cae9; position: absolute; transform: rotate(-45deg); left: 50%; top: 50%; margin: -20px 0 0 -20px; } .pin:after { content: ""; width: 14px; height: 14px; margin: 8px 0 0 8px; background: #e6e6e6; position: absolute; border-radius: 50%; } .bounce { animation-name: bounce; animation-fill-mode: both; animation-duration: 0.9s; } .pulse { background: #d6d4d4; border-radius: 50%; height: 14px; width: 14px; position: absolute; left: 50%; top: 50%; margin: 11px 0px 0px -12px; transform: rotateX(55deg); z-index: -2; } .pulse:after { content: ""; border-radius: 50%; height: 40px; width: 40px; position: absolute; margin: -13px 0 0 -13px; animation: pulsate 1s ease-out; animation-iteration-count: infinite; opacity: 0; box-shadow: 0 0 1px 2px #00cae9; animation-delay: 0.1s; } @keyframes pulsate { 0%, 100% { transform: scale(0.1, 0.1); opacity: 0; } 50% { opacity: 1; } 100% { transform: scale(1.2, 1.2); opacity: 0; } } @keyframes bounce { 0% { opacity: 0; transform: translateY(-1000px) rotate(-45deg); } 60% { opacity: 1; transform: translateY(5px) rotate(-45deg); } 80% { transform: translateY(-10px) rotate(-45deg); } 100% { transform: translateY(0) rotate(-45deg); } } .myBounceDiv { -moz-animation:bounce .40s linear; -webkit-animation:bounce .40s linear; } @-moz-keyframes bounce { 0%{ -moz-transform:scale(0); opacity:0;} 50%{ -moz-transform:scale(1.3); opacity:0.4; } 75%{ -moz-transform:scale(0.9); opacity:0.7;} 100%{ -moz-transform:scale(1); opacity:1;} } @-webkit-keyframes bounce { 0%{ -webkit-transform:scale(0); opacity:0;} 50%{ -webkit-transform:scale(1.3); opacity:0.4;} 75%{ -webkit-transform:scale(0.9); opacity:0.7;} 100%{ -webkit-transform:scale(1); opacity:1;} } @keyframes drop { 0% { transform: translateY(-40px) rotate(-45deg); } 80% { transform: translateY(3px) rotate(-45deg); } 100% { transform: translateY(0) rotate(-45deg); } } .drop { animation-name: drop; animation-fill-mode: both; animation-duration: 0.5s; } 
 <div class='myBounceDiv'> <div id="marker" class='pin bounce'></div> <div class='pulse'></div> </div> 
+3
source

Source: https://habr.com/ru/post/1274168/


All Articles