2

I'm wondering if respectively how it is possible to interweave Font Awesome Lock Icon and Font Awesome Lock Open Icon while toggling/animating them somehow smart. For example there is this flip animation.

<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/js/all.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" rel="stylesheet"/>
<div class="fa-5x">
  <i class="fas fa-lock fa-flip" style="--fa-animation-duration: 10s; color: red"></i>
  <i class="fas fa-unlock fa-flip" style="--fa-animation-duration: 10s; color: green"></i>
</div>

Now for instance it would make sense to superimpose both icons, set one to display: none and toggle them on click or on hover or whatever. But how to toggle them after half of the animation time so that the exchange takes place at the moment when the respective icon can only be seen as a line from the side? Or do you have a better idea for a reasonable animation?

  • 1
    I assume that you don't need it to keep flipping the whole time, just when an event is happening (user click or something else) you want it to flip animated and change the icon. If that's the case, in your code, when you want to change the icon you should add a class fa-flip and with a timeout change the fa-lock to fa-unlock – Mordy Stern Nov 08 '21 at 19:21
  • 1
    Yes, you're right. That's a good idea. Thank you! – Three Year Old Nov 08 '21 at 19:44

1 Answers1

1

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

const icon = document.getElementById('icon');
icon.addEventListener('click', () => {
  icon.classList.toggle('green');
});

const icon2 = document.getElementById('icon2');
icon2.addEventListener('click', () => {
  icon2.classList.toggle('green');
})
*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --bg: hsl(201, 27%, 10%);
}

body {
  height: 100vh;
  background: var(--bg);
  display: flex;
  justify-content: center;
  align-items:center;
  gap: 1em;
  position: relative;
}

#icon,
#icon2 {
  width: 52px;
  height: auto;
  position: relative;
  cursor: pointer;
}

#icon rect,
#icon path,
#icon2 path {
  transition: all 0.5s ease-in-out;
}

#icon rect {
  fill: red;
}
#icon2 path#body {
fill: red;
}

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

#icon.green rect,
#icon2.green path#body {
  fill: green;
}

#icon.green path,
#icon2.green path#hook {
  stroke: green;
  stroke-dasharray: 20;
}

/* keyhole */

#keyhole {
  width: 10px;
  height: 16px;
  border-radius: 25px;
  position: absolute;
  top: 65%;
  left: 50%;
  background-color: var(--bg);
  transform: translate(-50%, -50%) rotate(0deg);
  transition: all 0.5s ease-in-out;
  z-index: 1;
}

#icon.green #keyhole {
  transform: translate(-50%, -50%) rotate(-180deg);
}
<div id="icon">
  <div id="keyhole"></div>
  <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>

<div id="icon2">
  <svg viewBox="0 0 22 25"  xmlns="http://www.w3.org/2000/svg">
    <path id="hook" d="M5.73633 10.4592V7.32508C5.73633 4.31064 8.18002 1.86694 11.1944 1.86694C14.2089 1.86694 16.6526 4.31064 16.6526 7.32508V10.4592" stroke-width="3.5"/>
    <path id="body" d="M3.50537 10.1519H18.8831C20.5399 10.1519 21.8831 11.4951 21.8831 13.1519V21.4387C21.8831 23.0956 20.5399 24.4387 18.8831 24.4387H3.50537C1.84852 24.4387 0.505371 23.0956 0.505371 21.4387V13.1519C0.505371 11.4951 1.84852 10.1519 3.50537 10.1519ZM11.1945 13.9858C10.0865 13.9858 9.18823 14.884 9.18823 15.9921V18.3328C9.18823 19.4408 10.0865 20.3391 11.1945 20.3391C12.3026 20.3391 13.2008 19.4408 13.2008 18.3328V15.9921C13.2008 14.884 12.3026 13.9858 11.1945 13.9858Z"/>
  </svg>
</div>
Anton
  • 8,058
  • 1
  • 9
  • 27
  • This is great! :) – Three Year Old Nov 12 '21 at 16:51
  • How would you animate the lock icon if the entered password is wrong? My idea would be to let the red lock icon tremble while it briefly pulsates in color (transition from red to yellow and back to red again). What do you think? Or do you have a better idea? – Three Year Old Nov 13 '21 at 12:14
  • Could you add the same unlock/lock effect for [this slightly different icon](https://fontawesome.com/v5.15/icons/lock-alt?style=solid)? – Three Year Old Nov 13 '21 at 12:18
  • I suppose the best way not touch lock icon, you have two states for lock and unlock, a third state would be overkill. Instead, you can to create some notification text about wrong password and why it is wrong. This is a more `user friendly` to know what happened. Updated snippet. – Anton Nov 13 '21 at 13:43
  • 1
    Well, and if I only use the unlock effect from your solution but not the lock effect? Then the animation of the lock icon if the entered password is wrong would only be a second state and not a third. -- Great! Thank you! :) – Three Year Old Nov 13 '21 at 14:11
  • What do you think of rotating the keyhole 360 degrees clockwise before the shackle opens? I think that would be really cool. But I'm not sure what would be the best way to realise that. Would I have to put a second SVG (just the keyhole with a border) over the padlock? Or is it also possible in a simpler way? – Three Year Old Nov 13 '21 at 20:44
  • 1
    To create and animate the keyhole, add extra div inside `id=#icon` with `position: absolute`, `border-radius` and `background-color` must same be the color as a main background. Of couse, `id=#icon` must have `position: relative.` – Anton Nov 13 '21 at 21:14
  • Thanks for your fast answer. So you wouldn't use another SVG? `
    ` is not exact. And most importantly, it's not responsive, isn't it?
    – Three Year Old Nov 13 '21 at 21:51
  • 1
    Updated snippet. – Anton Nov 13 '21 at 22:17
  • Thank you very much! That's really cool! :) I added `transition-delay: 0.5s;` to `#icon rect, #icon path` so that first the key is turned and then the lock opens. But one last thing: What about responsiveness of the keyhole? So if the size of the padlock changes, the keyhole adpats? – Three Year Old Nov 14 '21 at 11:16
  • 1
    You can use the logical css [functions](https://web.dev/min-max-clamp/) for keyhole or replace static **px** units, to flexible `em, rem, %, vh, vw`. – Anton Nov 14 '21 at 11:52
  • Which one would you prefer? With `width: 0.6em; height: 0.9em; border-radius: 0.3em;` for example the keyhole is deformed during the animation. – Three Year Old Nov 14 '21 at 12:49
  • Anyway, you helped me a lot, thank you very much for that. :) – Three Year Old Nov 16 '21 at 16:49