CSS-animation-按钮呼吸态

6,354 阅读8分钟

写在前面 

笔者最近面试恰好碰到此题,以往做这类的需求往往都是问设计师要两张呼吸前后的图片,更或者直接GIF完事,真要开始纯用CSS3的一时半会摸不着头脑,于是乎自己准备认真撸上一发按钮呼吸,看看有什么幺蛾子。 首先先看别人家的预览图,咱们得照着做一个:

                                                  

第一眼分析:

  1. 中间白圈内若隐若现
  2. 两边白圈成波纹铺开

1.第一步,先找到一张箭头图

笔者去阿里font白嫖了一张~

为了比较好看出效果,采取了透明底图片,dom元素深色背景。如下

2.开始造圈圈

<div id="breath-btn">        
    <div id="inner" class="white-border">            
        <img class="arrow" src="./arrow.png" />        
     </div> 
</div>

html, body {
    height: 100vh;
    background: #0078db;

}

#breath-btn {
    width: 80px;
    height: 80px;
    position: relative;
    display: inline-block;
    margin: auto 50%;
    margin-top: 200px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.white-border{
    border: 2px solid #fff;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 50px;
    height: 50px;
}

.arrow {
    width: 70%;
}

差不多整体布局出来了

3.中间白圈内若隐若现

通过写个动画@keyframes来定义

#inner {
    animation: OpacityBreath 2s ease-in-out infinite;
    opacity: 0.3;
}

@keyframes OpacityBreath {
    0% {
        opacity: 0.3;
    }

    50% {
        opacity: 0.65;
    }

    100% {
        opacity: 0.3;
    }
}

看起来像回事,先暂定如此。

4.创造波纹

重头戏来了。通过慢放仔细观察,发现外圈率先弹出,但是内圈速度更快。至于做法采用transform的scale把圈子扩大,同时加上透明度变化。外层的波纹都用伪类来做节省dom元素,活用伪类真方便。

#breath-btn::before,
#breath-btn::after {
    content: '';
    border: 2px solid #fff;
    width: 50px;
    height: 50px;
    position: absolute;
    opacity: 0;
    border-radius: 50%;
}

@keyframes Wave {
    0% {
        transform: scale(1);
        opacity: 0.3;
    }

    100% {
        transform: scale(2);
        opacity: 0;
    }
}

5.波纹动起来。

看到这里想让波纹动起来应该没啥难度吧,笔者当时也这么想。不假思索的写下以下样式

#breath-btn::before {
    animation: Wave 1.1s ease-in-out infinite;
}

#breath-btn::after {
    animation: Wave 0.7s ease-in-out 0.4s infinite;
}

最外层的圈设置1.1s走完,内层速度要快0.7s,0.4s延迟时间,造成视觉上的追击感。但是问题来了,animation的delay time只有第一次生效,这真的是坑爹啊,第一次追击成功后面整个就是乱套,真希望CSS能把这个属性在补强一点。于是乎笔者最后采用脚本解决:

.breath-btn-animation::before {    
   animation: Wave 1.1s ease-in-out;
}
.breath-btn-animation::after {    
    animation: Wave 0.7s ease-in-out 0.4s;
}

<body>
    <div id="breath-btn">
        <div id="inner" class="white-border">
            <img class="arrow" src="./arrow.png" />
        </div>
    </div>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <script>
        function toggleWave() {
            $('#breath-btn').toggleClass('breath-btn-animation');

            setTimeout(() => {
                toggleWave()
            }, 1800)
        }
        toggleWave();
    </script>
</body>

通过jquery动态切换breath-btn-animation,让两层波纹圈跳动一次,再设置延迟时间,最终效果如下:

最终效果相差无几,需要调整的就是动画时间和曲线算法了。

总结

开发小小的一个按钮呼吸态,不禁感叹CSS是真神奇,开发途中还遇到一个transform-origin的问题导致更改了布局采用了伪类,这个放到下期再研究吧。

ps(掘金的富文本编辑太难用了,复制代码一定要纯文本粘贴,不然换行符GG)