1

I pick up on this question.

$('.lock').click(function() {
  $('.fa-lock', this).addClass('fa-flip');
  $('.fa-unlock', this).addClass('fa-flip');
  setTimeout(function() {
    $('.fa-lock').css('color', 'rgba(0, 0, 0, 0)');
    $('.fa-unlock').css('color', 'green');
  }, 600);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" rel="stylesheet" />
<style>
  @keyframes halfflip {
    to {
      transform: rotateY(360deg);
    }
  }
  
  .fa-flip {
    animation-name: halfflip;
    animation-timing-function: ease-in-out;
  }
  
</style>
<div class="fa-5x fa-stack lock">
  <i class="fas fa-unlock fa-stack-1x" style="--fa-animation-duration: 4s; --fa-animation-iteration-count: 1; color: transparent; animation-fill-mode: forwards; --fa-animation-delay:-2s"></i>
  <i class="fas fa-lock fa-stack-1x" style="--fa-animation-duration: 4s; --fa-animation-iteration-count: 1; color: red; animation-fill-mode: forwards; --fa-animation-delay:-2s"></i>
</div>

A click on the red lock icon starts an animation which leads to the green unlock icon. Now a click on the green unlock icon should do the corresponding opposite. How to toggle both icons?

2 Answers2

1

You can adjust the JS to save whether or not it's in a locked state in a variable that you check to apply the correct styling and flip it after each time, like this

let locked = true;
$('.lock').click(() => {
  $('.fa-lock', this).addClass('fa-flip');
  $('.fa-unlock', this).addClass('fa-flip');
  setTimeout(function() {
    if (locked) {
      $('.fa-lock').css('color', 'rgba(0, 0, 0, 0)');
      $('.fa-unlock').css('color', 'green');
    } else {
      $('.fa-lock').css('color', 'red');
      $('.fa-unlock').css('color', 'rgba(0, 0, 0, 0)');
    }
    locked = !locked;
  }, 100); // To change lock & unlock speed. 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" rel="stylesheet" />
<style>
  @keyframes halfflip {
    to {
      transform: rotateY(360deg);
    }
  }
  
  .fa-flip {
    animation-name: halfflip;
    animation-timing-function: ease-in-out;
  }
  
</style>
<div class="fa-5x fa-stack lock">
  <i class="fas fa-unlock fa-stack-1x" style="--fa-animation-duration: 4s; --fa-animation-iteration-count: 1; color: transparent; animation-fill-mode: forwards; --fa-animation-delay:-2s"></i>
  <i class="fas fa-lock fa-stack-1x" style="--fa-animation-duration: 4s; --fa-animation-iteration-count: 1; color: red; animation-fill-mode: forwards; --fa-animation-delay:-2s"></i>
</div>
Kameron
  • 10,240
  • 4
  • 13
  • 26
Fran
  • 21
  • 3
  • Thank you! But what about the animation? – Three Year Old Nov 09 '21 at 19:14
  • Sorry, forgot about the animation part. The original example's animation is actually not working for me as is. Do you have a working example I can run? – Fran Nov 09 '21 at 20:01
  • The animation works!? – Three Year Old Nov 09 '21 at 20:27
  • Weird, it wasn't working in my other browser before. I believe if you remove the class and re-add it, it'll do the animation again. Try $('.fa-lock', this).removeClass('fa-flip'); $('.fa-unlock', this).removeClass('fa-flip'); $('.fa-lock', this).addClass('fa-flip'); $('.fa-unlock', this).addClass('fa-flip'); – Fran Nov 09 '21 at 21:13
  • I'm having trouble testing the animation at the moment, but this other answer may help you with the animation part. https://stackoverflow.com/questions/6268508/restart-animation-in-css3-any-better-way-than-removing-the-element – Fran Nov 09 '21 at 21:21
  • Doesn't work. :( – Three Year Old Nov 10 '21 at 16:16
1

You can't animate two different icons to get a real unlock effect. But, if not critical, you can create your own svg icon and animate.

unlock effect

$('#icon').click(function() {
  $('#icon').toggleClass('green');
});
*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  height: 100vh;
  background-color: hsl(201, 27%, 10%);
  color: white;
  display: grid;
  place-items: center;
  position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" rel="stylesheet" />

<style>
#icon {
  width: 52px; /* adjust icon size  */
  height: auto;
  cursor: pointer;
}
#icon rect,
#icon path {
  transition: all 0.5s ease-in-out;
}

#icon rect {
  fill: red;
}
#icon path {
  stroke: red;
  stroke-dasharray: 30;
  stroke-dashoffset: 5;
  fill: none;
}

#icon.green rect {
  fill: green;
}
#icon.green path {
  stroke: green;
  stroke-dasharray: 20;
}
</style>

<div id="icon" class="fa-5x fa-stack lock">
  <svg viewBox="0 0 22 25">
    <rect x="0.505493" y="10.1519" width="21.3777" height="14.2868" rx="3"/>
    <path d="M5.73621 10.4592V7.32508C5.73621 4.31064 8.1799 1.86694 11.1943 1.86694V1.86694C14.2088 1.86694 16.6525 4.31064 16.6525 7.32508V10.4592"stroke-width="3.5" />
  </svg>
</div>

rotation effect

$('#box').click(function() {
  $('#box').toggleClass('unlock');
});
*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  height: 100vh;
  background-color: hsl(201, 27%, 10%);
  color: white;
  display: grid;
  place-items: center;
  position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" rel="stylesheet" />

<style>
   :root {
    --duration-rotate: 1s;
    --delay: 1s;
  }
  
  #green,
  #red {
    backface-visibility: visible;
    transition: all var(--duration-rotate) ease-in-out;
  }
  
  #red {
    transition-delay: var(--delay);
  }
  
  #green {
    transform: rotateY(-270deg);
    transition-delay: 0s;
  }
  
  #box.unlock #red {
    transform: rotateY(90deg);
    backface-visibility: hidden;
    transition-delay: 0s;
  }
  
  #box.unlock #green {
    transform: rotateY(-360deg);
    backface-visibility: visible;
    transition-delay: var(--delay);
  }
</style>

<div id="box" class="fa-5x fa-stack lock">
  <i id="green" class="fas fa-unlock fa-stack-1x" style="color: green"></i>
  <i id="red" class="fas fa-lock fa-stack-1x" style="color: red"></i>
</div>
Anton
  • 8,058
  • 1
  • 9
  • 27
  • Yes, I can. Didn't you see the animation in my snippet? Your animations is really nice, except the SVG is not clean and there is a black background in the area of the bracket. What do you mean with "not critical"? – Three Year Old Nov 11 '21 at 19:42
  • 1
    I saw animation, but this is a rotation transform, switching between two icon and this is not an unlock animation as it is (that's just my opinion). I mean `not critical` if you use on your projecy only *Font Awesome* and some cause you can to use additional icons. Oh, my bad, i forgot to add to the *path* `fill:none`. The snippet updated. – Anton Nov 11 '21 at 20:21
  • Actually you're right. Now your animation is just (font) awesome. :) I really like it. Thank you very much! (I'd like to accept your answer, but as it doesn't exactly answer my question, maybe you could add a solution tailored to my snippet. Even though your solution is much better.) (Your answer actually fits my [original question](https://stackoverflow.com/questions/69888696/how-to-reasonably-animate-font-awesome-lock-icons).) Unfortunately I still don't understand the "not critical" point. – Three Year Old Nov 12 '21 at 12:19
  • 1
    No problem, i will can to move this answer to another your question to accept this. And when you accepted, i can remove answer here. Will try to explain short. In some projects is required solve issue only with css and html without javascript. And this is `critical` = `important` for project for some reason, maybe backend or optimization. `not critical` = you need to solve problem and does not matter how, this will be solved. English is not my native language, to explain it currectly. – Anton Nov 12 '21 at 15:02
  • Please don't delete your answer here. Could you add a solution tailored to my snippet? -- Now I understand. `critical` = `without JS` and `not critical` = `potentially with JS`. Since I also used JavaScript in my question, `not critical` can be assumed. Thank you! – Three Year Old Nov 12 '21 at 16:49
  • Thank you! But you got me wrong. I meant just a minor change to my snippet so that the rotation transform from red lock icon to green unlock icon, which is beeing executed by clicking on the red lock icon, will be quasi reversed by clicking on the green unlock icon. – Three Year Old Nov 12 '21 at 19:52
  • 1
    Updated snippet. – Anton Nov 12 '21 at 21:26