前几篇介绍了CSS3的3个动画属性transform,transition,animation。但即使基本语法能看懂,也不代表能设计出棒棒的动画效果。在设计这条路上,是学无止境,甚至需要拼天赋的。我也很菜,只能站在优秀的设计师的肩膀上,模拟出一些效果。
例如非常常见的Loading的效果,你完全可以用GIF来实现。但GIF有它的局限,例如颜色数量被限制在256色。不具备Alpha透明,导致无法做出半透明效果。不够灵活,一旦GIF动画生成后,例如动画持续时间,循环次数等都固定住了,要想修改,只能用图像处理软件再去编辑GIF。
因此我们用CSS3来实现动画效果,参照网上的设计,分享一下常见的Loading。你可以点这里
例子1:菊花状的Loading效果
第一步画出静态的小菊花。
.sk-fading-circle { width: 40px; height: 40px; position: relative; } .sk-fading-circle .sk-circle { width: 100%; height: 100%; position: absolute; left: 0; top: 0; } .sk-fading-circle .sk-circle:before { content: ''; display: block; margin: 0 auto; width: 15%; height: 15%; background-color: #333; border-radius: 100%; }<div class="sk-fading-circle"> <div class="sk-circle"></div> … //为缩减篇幅省略中间10个div <div class="sk-circle"></div></div>
代码如上,静态小菊花其实是一个外层div里嵌套12个小div。小div通过 border-radius画成圆型,并通过margin: 0 auto;定位到顶格居中位置。由于12个小div都是absolute定位,因此都重叠在了一起。
第二步将12个重叠的圆分散开。
.sk-fading-circle .sk-circle2 { transform: rotate(30deg);} .sk-fading-circle .sk-circle3 { transform: rotate(60deg);} … //节省篇幅,每个圆每隔30度递增旋转 .sk-fading-circle .sk-circle12 { transform: rotate(330deg);}<div class="sk-fading-circle"> <div class="sk-circle1 sk-circle"></div> … //为缩减篇幅省略中间10个div <div class="sk-circle12sk-circle"></div></div>
代码如上,用transform的rotate将各个圆点旋转,形成完整的菊花状。如果你对transform不熟的话,看下图,第二个圆点旋转30度的示意图,其余圆点的旋转自行脑补:
第三步通过animation控制opacity属性,让每个点淡进淡出
@-webkit-keyframes sk-circleFadeDelay { 0%, 39%, 100% { opacity: 0; } 40% { opacity: 1; } }@keyframes sk-circleFadeDelay { 0%, 39%, 100% { opacity: 0; } 40% { opacity: 1; } } .sk-fading-circle .sk-circle:before { …… animation: sk-circleFadeDelay 1.2s infinite ease-in-out both; }
这样每个点都在像信号灯一样同步地闪烁。
最后一步,给每个点设置animation-delay延时,以错开闪烁的时间,形成常见的菊花转转的效果
.sk-fading-circle .sk-circle2:before {animation-delay: -1.1s; } .sk-fading-circle .sk-circle3:before { animation-delay: -1s; } .sk-fading-circle .sk-circle4:before { animation-delay: -0.9s; } … //为缩减篇幅省略中间代码.sk-fading-circle .sk-circle12:before { animation-delay: -0.1s; }
因为是12个圆点,每个圆点的闪烁间隔时间0.1s,因此第1个圆点没有animation-delay延时,立即闪烁。第二个圆点,从-1.1s开始闪烁(负数不理解的话,参考animation一文,意思是从该时间点开始启动,之前的动画效果不显示)。之后每个圆点均以0.1s递增的速度延迟。最终形成常见的菊花转转的Loading效果
例子2:ios版菊花Loading
明白了原理后,无非是在例子1的基础上,将圆点改成竖条,opacity半透明即可。你可以在例子页面自行查看源码
例子3:菊花状的Loading效果(用PNG实现)
上面的例子纯CSS实现Loading效果,缺点是除了需要一定的设计天赋外,如果将来需求变了,需要加上一点其他效果时,维护起来也有一定的技术门槛。包括源代码中HTML和CSS的体积比较大。其实也可以用绘图软件,根据需求,先制作出一张静态的PNG图:
如上面8帧图,每张都是100*100大小,合并后是一张800*100的PNG图。我们先将第一帧的图显示出来:
.loader { width: 100px; height: 100px; text-indent: 999px; overflow: hidden; /* Hide text */ background-image: url(loader.png); } <div class="loader">Loading...</div>
div的大小设为100*100px正好只够显示第一帧的背景图。现在加上动画效果,即通过background-position: -100px, 0;
让整张图往左偏移100px来显示下一帧的图。但显然不能线性偏移,需要将默认值ease改成steps(8):
@keyframes loader { to { background-position: -800px 0; } } .loader { …… animation: loader 1s infinite steps(8); }
上面的动画效果代码非常短,就2,3行而已,每秒通过steps函数切换8次,每次切换就是将整张图往左偏移100px,效果点这里。究竟是要HTML,CSS体积小,用PNG配合CSS来实现,还是纯CSS来实现,都有优劣,并无固定标准。
例子4:琴谱版Loading
第一步,画出静态琴谱,很简单无非是一个外层div,内嵌几个并排的div而已
.spinner { height: 40px; } .spinner > div { background-color: #333; height: 100%; width: 6px; display: inline-block; } <div class="spinner"> <div></div> … //你可以根据需求多加几个div <div></div> </div>
第二步,琴谱动起来
.spinner > div { …… animation: sk-stretchdelay 1.2s infinite ease-in-out; } @keyframes sk-stretchdelay { 0%, 40%, 100% { transform: scaleY(0.4); } 20% { transform: scaleY(1.0); } }
例1,2中用了transform的rotate实现旋转。例3用了transform的scaleY实现拉伸。
最后一步,设置延时,让每个琴键在不同时间内拉伸
.spinner .rect2 { animation-delay: -1.1s; } .spinner .rect3 { animation-delay: -1.0s; } .spinner .rect4 { animation-delay: -0.9s; } .spinner .rect5 { animation-delay: -0.8s; }<div class="spinner"> <div class="rect1"></div> … //为节省篇幅省略中间代码 <div class="rect5"></div></div>
每个琴键的拉伸间隔时间0.1s,因此第1个琴键没有animation-delay延时,立即拉伸。第二个琴键,从-1.1s开始闪烁。之后每个琴键均以0.1s递增的速度拉伸。和菊花Loading的原理是一样的,不赘述。
例子5:简书版Loading
明白了原理后,无非是在例子3的基础上,将琴键改成原点,改改颜色即可。你可以在例子页面自行查看源码
总结
更多的Loading例子,网上有很多优秀的例子,例如cssload。但Loading的动画效果最多只能算一盘餐前小点,你可以充分挖掘CSS3的动画属性的潜力,制作出更炫的效果。
作者:张歆琳
链接:https://www.jianshu.com/p/55372466ce70
共同学习,写下你的评论
评论加载中...
作者其他优质文章