在Apple watch上新上了一个呼吸灯的应用,主界面有一个呼吸的动画。这篇文章,就来讲讲如何使用CSS来实现下这个呼吸的动画效果,如下图所示:
实现圆圈
第一件事情就是先要实现静态的UI。从上图可以看出整个动画其实是由六个圆圈组成,如果按正常的布局来实现的话,要使用6个div结构。不过如果使用伪元素的话,比如 ::before和::after不仅可以减少div节点,还可以使html结构保持足够的简单。当然我们这里还是按正常的方法来实现。
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
然后就来写样式,每个圆的尺寸是125px。因为动画中的每个圆都是彼此叠加的,所以这里需要使用绝对定位来实现UI布局。
.circle {
border-radius: 50%;
height: 125px;
position: absolute;
transform: translate(0, 0);
width: 125px;
}
需要注意的是,我们这里使用transform方法中的translate属性来实现动画,比起使用top,right来性能更加高效,动画也更加顺滑。
首先是设置圆圈的背景颜色,先把它设置为白色的背景,然后调整下它的透明度:
body {
background: #000;
}
.circle {
background: #fff;
height: 125px;
width: 125px;
border-radius: 50%;
position: absolute;
opacity: 0.75;
transform: translate(0, 0);
}
调整布局
到上一步,你会发现,现在圆圈是在视窗的左上角的。按照最初的设想,是要居中显示的。所以,需要在圆圈结构外面加一层结构把它包裹起来,这样就很容易实现居中的视觉效果。
添加一个.watch-face类,宽高和圆圈一样。
<div class="watch-face">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
然后使用,flex来实现元素的居中视觉效果。
body {
background: #000;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
编写动画
在编写动画前,需要花点时间把圆圈定位在它们应该在的位置。这里推荐使用nth-child这个选择器来选择需要定位的元素,这样就不需要给每个元素定义一个类了。
.circle:nth-child(1) {
transform: translate(-35px, -50px);
}
/* Skipping 2-5 for brevity... */
.circle:nth-child(6) {
transform: translate(35px, 50px);
}
至于怎么来确定圆圈具体的位置,这个就要自己一点一点来调了,最后的效果如下所示:
因为动画也是用transform来做的,所以需要把之前用来布局用的transform移除,一起写入到动画的keyframes中去:
@keyframes circle-1 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-35px, -50px);
}
}
/* And so on... */
因为每一个圆圈的动画都是不一样的,所以我们还是需要使用:nth-child选择器来给每一个圆圈指定对应的动画。
.circle:nth-child(1) {
animation: circle-1 4s ease alternate infinite;
}
/* And so on... */
需要注意的是animation-timing-function我们指定的是ease,这样可以使动画看起来更加顺滑。animation-direction设置为alternate,这样使动画来回运动。animation-iteration-count设置为inifinite,使动画一直循环播放。
修改视觉
基本动画完成,接下里为了和Apple watch中的动画更接近,还需要调整下圆圈的颜色。
从Apple watch中可以看到,左边的圆圈是浅浅的绿色,右边是浅蓝色。选择奇数的圆圈赋予浅绿色,偶数的圆圈赋予浅蓝色。
.circle:nth-child(odd) {
background: #61bea2;
}
.circle:nth-child(even) {
background: #529ca0;
}
最后,要记得把之前定义的.circle元素的白色背景颜色删除掉。
在文章的评论中,有小伙伴们指出可以使用mix-blend-mode为screen来代替opacity。这样可以使圆圈的颜色相互融合在一起。
缩放和旋转动画
还记得我们添加的.watch-face这个结构么?我们就使用它来创建缩放和旋转动画。
@keyframes pulse {
0% {
transform: scale(.15) rotate(180deg);
}
100% {
transform: scale(1);
}
}
然后给.watch-face元素来指定动画。
.watch-face {
height: 125px;
width: 125px;
animation: pulse 4s cubic-bezier(0.5, 0, 0.5, 1) alternate infinite;
}
为了使动画运动起来更加的自然,可以把animation-timing-function的值替换为cubic-bezier曲线。
最后,把代码全部整合起来,就完成了文章开头介绍的动画效果。
本文主要是从Recreating the Apple Watch Breathe App Animation这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!