You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合理实现Font Awesome锁形图标切换时的流畅动画效果

锁形图标翻转动画切换实现方案

实现核心原理

Font Awesome自带的flip动画本质是Y轴旋转,当旋转到90°时图标刚好处于侧面仅显示细线的状态,此时切换两个图标的显隐状态,就能实现翻转到中间换图的效果。


方案1:纯CSS实现(适合hover触发场景)

代码示例

<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"/>
<style>
.icon-wrap {
  position: relative;
  font-size: 5rem;
  perspective: 1000px; /* 开启3D透视效果 */
  cursor: pointer;
}
.icon-wrap i {
  position: absolute;
  left: 0;
  top: 0;
  transition: visibility 0s;
}
.lock {
  color: red;
}
.unlock {
  color: green;
  visibility: hidden; /* 初始隐藏解锁图标 */
}
/* hover触发翻转动画 */
.icon-wrap:hover .lock {
  animation: flipSwitch 2s forwards;
}
.icon-wrap:hover .unlock {
  animation: flipSwitch 2s forwards reverse;
}
@keyframes flipSwitch {
  0% {
    transform: rotateY(0deg);
    visibility: visible;
  }
  49.9% {
    visibility: visible;
  }
  50% {
    transform: rotateY(90deg);
    visibility: hidden;
  }
  100% {
    transform: rotateY(180deg);
    visibility: hidden;
  }
}
</style>
<div class="icon-wrap">
  <i class="fas fa-lock lock"></i>
  <i class="fas fa-unlock unlock"></i>
</div>

说明

  • 动画总时长可自行调整,forwards 属性保证动画结束后保持最终状态
  • 50%节点刚好对应旋转90°的侧面状态,此时切换显隐不会有跳变感

方案2:JS控制(适合点击、自定义事件触发场景)

代码示例

<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"/>
<style>
.icon-wrap {
  position: relative;
  font-size: 5rem;
  perspective: 1000px;
  cursor: pointer;
}
.icon-wrap i {
  position: absolute;
  left: 0;
  top: 0;
}
.lock {
  color: red;
}
.unlock {
  color: green;
  display: none;
}
.flipping {
  animation: flipHalf 1s linear;
}
@keyframes flipHalf {
  from { transform: rotateY(0deg); }
  to { transform: rotateY(90deg); }
}
</style>
<div class="icon-wrap" id="lockBtn">
  <i class="fas fa-lock lock"></i>
  <i class="fas fa-unlock unlock"></i>
</div>
<script>
const lockBtn = document.getElementById('lockBtn');
const lockIcon = lockBtn.querySelector('.lock');
const unlockIcon = lockBtn.querySelector('.unlock');
const animDuration = 1000; // 半程动画时长,全程总时长为2倍该值
let isLocked = true;
lockBtn.addEventListener('click', () => {
  // 先执行前半段翻转到90度
  lockIcon.classList.add('flipping');
  unlockIcon.classList.add('flipping');
  
  setTimeout(() => {
    // 半程时切换显隐
    isLocked = !isLocked;
    lockIcon.style.display = isLocked ? 'block' : 'none';
    unlockIcon.style.display = isLocked ? 'none' : 'block';
    
    // 执行后半段从90度翻转到180度
    lockIcon.classList.remove('flipping');
    unlockIcon.classList.remove('flipping');
    lockIcon.style.transform = isLocked ? 'rotateY(0deg)' : 'rotateY(180deg)';
    unlockIcon.style.transform = isLocked ? 'rotateY(180deg)' : 'rotateY(0deg)';
  }, animDuration)
})
</script>

说明

  • 可根据业务需求修改触发事件,比如表单验证通过自动触发切换
  • 半程动画时长可自行调整,定时器时长和CSS动画时长保持一致即可

替代优化方案

如果不想同时放两个图标,也可以直接修改单个图标的类名配合transform实现,代码更简洁:

// 点击时半程切换类名
setTimeout(() => {
  icon.classList.toggle('fa-lock');
  icon.classList.toggle('fa-unlock');
  icon.style.color = icon.classList.contains('fa-lock') ? 'red' : 'green';
}, animDuration)

内容的提问来源于stack exchange,提问作者Three Year Old

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:24:05