纯CSS实现带粒子动画的按钮切换效果

346 阅读2分钟

我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!

前言

之前通过GSAP这个动画库实现过JS+CSS的按钮切换效果,今天通过纯CSS的方式来实现

通过码上掘金体验效果

实现步骤

初始化的dom节点和css

input是用来控制点击切换样式

spark是四个荧光点,点击按钮会显示这个,其他就是用于button的样式

<div class="switch">
   <input type="checkbox" name="toggle">
   <label for="toggle">
    <i class="bulb">
      <span class="bulb-center"></span>
      <span class="filament-1"></span>
      <span class="filament-2"></span>
      <span class="reflections">
        <span></span>
      </span>
      <span class="sparks">
        <i class="spark1"></i>
        <i class="spark2"></i>
        <i class="spark3"></i>
        <i class="spark4"></i>
      </span>
    </i>    
  </label>
</div>

初始化样式文件过长这边就不贴了,可以查看源码

主要是通过input:checked的CSS控制样式的切换,下面的checked改变的样式,主要改变以下几点

  • background-color
  • box-shadow
  • left
    .switch input:checked ~ label .bulb {
      left: 120px;
      background-color: #a7694a;
      box-shadow: inset 0 0 1px 3px #a56758, inset 0 0 6px 8px #6b454f,
        0 20px 30px -10px rgba(0, 0, 0, 0.4),
        0 0 30px 50px rgba(253, 184, 67, 0.1);
    }
    .switch input:checked ~ label .bulb > .bulb-center {
      background-color: #feed6b;
      box-shadow: inset 0 0 0 4px #fdec6a, 0 0 12px 10px #bca83c,
        0 0 20px 14px #a1664a;
    }
    .switch input:checked ~ label .bulb > .bulb-center:after {
      background-color: #fef401;
      box-shadow: 0 0 2px 4px #fdb843;
    }
    .switch input:checked ~ label .bulb > .filament-1:before,
    .switch input:checked ~ label .bulb > .filament-2:before,
    .switch input:checked ~ label .bulb > .filament-1:after,
    .switch input:checked ~ label .bulb > .filament-2:after {
      border-color: #fef4d5;
    }

这个时候还没有荧光的效果,我们需要加上对应的css和keyframe,分别代表四个荧光点的样式效果,四个分别对应四个不同的变化方式,可以通过不断调整找到合适的移动效果

    .switch input:checked ~ label .bulb > .sparks .spark1 {
      height: 1px;
      width: 1px;
      animation: spark1 2s ease-in-out;
      animation-delay: 0.4s;
    }
    .switch input:checked ~ label .bulb > .sparks .spark2 {
      height: 1px;
      width: 1px;
      animation: spark2 2.4s ease-in-out;
      animation-delay: 0.4s;
    }
    .switch input:checked ~ label .bulb > .sparks .spark3 {
      height: 1px;
      width: 1px;
      animation: spark3 2s ease-in-out;
      animation-delay: 0.9s;
    }
    .switch input:checked ~ label .bulb > .sparks .spark4 {
      height: 1px;
      width: 1px;
      animation: spark4 1.7s ease-in-out;
      animation-delay: 0.9s;
    }
    @keyframes spark1 {
      0% {
        right: -5px;
        height: 1px;
        width: 1px;
        opacity: 0;
      }
      20% {
        height: 3px;
        width: 3px;
        right: 0px;
        opacity: 1;
      }
      30% {
        right: -5px;
        opacity: 1;
        height: 3px;
        width: 3px;
      }
      70% {
        height: 3px;
        width: 3px;
      }
      100% {
        right: -60px;
        bottom: 40px;
        opacity: 0;
      }
    }

    @keyframes spark2 {
      0% {
        height: 3px;
        width: 3px;
        opacity: 0;
      }
      30% {
        opacity: 1;
      }
      100% {
        right: -20px;
        bottom: 100px;
        opacity: 0;
      }
    }

    @keyframes spark3 {
      0% {
        opacity: 0;
      }
      30% {
        opacity: 1;
        height: 2px;
        width: 2px;
      }
      100% {
        left: 0px;
        bottom: 100px;
        opacity: 0;
        height: 3px;
        width: 3px;
      }
    }

    @keyframes spark4 {
      0% {
        opacity: 0;
      }
      30% {
        opacity: 1;
        height: 2px;
        width: 2px;
      }
      100% {
        left: -20px;
        bottom: -10px;
        opacity: 0;
        height: 3px;
        width: 3px;
      }
    }