今日,群友提问,如何实现这么一个 Loading 效果:

这个确实有点意思,但是这是 CSS 能够完成的?

没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们之前的:

圆弧的实现

首先,我们可能需要实现这样一段圆弧:

这里需要用到的技术是:

角向渐变 conic-gradient() + mask 以及两个伪元素。图片示意如下:

核心代码如下图:

<div class="g-container">
<div class="g-circle"></div>
</div>
:root {
--headColor: hsl(130, 75%, 75%);
--endColor: hsl(60, 75%, 40%);
}
.g-container {
position: relative;
background: #000;
}
.g-circle {
position: relative;
width: 300px;
height: 300px;
border-radius: 50%;
background: conic-gradient(
var(--headColor) 0,
var(--headColor) 10%,
hsl(120, 75%, 70%),
hsl(110, 75%, 65%),
hsl(100, 75%, 60%),
hsl(90, 75%, 55%),
hsl(80, 75%, 50%),
hsl(70, 75%, 45%),
var(--endColor) 30%,
var(--endColor) 35%,
transparent 35%
);
mask: radial-gradient(transparent, transparent 119px, #000 120px, #000 120px, #000 100%); &::before,
&::after {
content: "";
position: absolute;
inset: 0;
width: 30px;
height: 30px;
background: var(--headColor);
top: 0;
left: 135px;
border-radius: 50%;
} &::after {
background: var(--endColor);
left: unset;
top: 214px;
right: 26px;
}
}

这样,我们就得到了这样一个图形:

气泡的实现

接下来,我们来实现尾部气泡向外扩散的效果。

由于这里涉及了多个气泡的不同运动动画,多个标签元素肯定是少不了了。

因此,接下来我们要做的事情:

  1. 我们需要多一组元素,将其绝对定位到上述圆环的头部或者尾部
  2. 给每个子元素随机设置多个大小不一的圆,颜色保持一致
  3. 给每个子元素随机设置不同方向的,向外扩散的位移动画
  4. 给每个子元素随机设置负的 animation-delay,造成动画上的先后顺序,并以此形成整个无限循环的气泡扩散动画

这里,由于有许多小气泡的动画,这个数量,我设置成了 100。那肯定是不能一个一个手写它们的动画代码,需要借助 SASS/LESS 等预处理器的循环、随机等函数。

核心代码如下:

<div class="g-container">
<div class="g-circle"></div>
<ul class="g-bubbles">
<li class="g-bubble"></li>
// ... 共 100 个 bubble 元素
<li class="g-bubble"></li>
</ul>
</div>
// 上面圆环的代码,保持一致,下面只补充气泡动画的代码
.g-bubbles {
position: absolute;
width: 30px;
height: 30px;
border-radius: 50px;
top: 100px;
left: 235px;
background: var(--headColor);
} .g-bubble {
position: absolute;
border-radius: 50%;
background-color: inherit;
} @for $i from 1 through 100 {
.g-bubble:nth-child(#{$i}) {
--rotate: calc(#{random(360)} * 1deg);
--dis: calc(#{random(100)} * 1px);
--width: calc(3px + #{random(25)} * 1px);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: var(--width);
height: var(--width);
animation: move #{(random(1500) + 1500) / 1000}s ease-in-out -#{random(3000) / 1000}s infinite;
}
} @keyframes move {
0% {
transform: translate(-50%, -50%) rotate(0deg);
}
75% {
opacity: .9;
}
100% {
transform: rotateZ(var(--rotate)) translate(-50%, var(--dis));
opacity: .4;
}
}

核心在于 @for $i from 1 through 100 { } 这段 SASS 代码内部,我们实现了上面说的 (2)(3)(4) 的功能点!

这样,我们就得到了这样一个效果,在尾部有大量气泡动画,不断向外扩散的效果:

借助滤镜实现粘性气泡效果

OK,到这里整个效果基本就做完了。当然,也是剩下最后最重要的一步,需要让多个气泡之间产生一种粘性融合的效果。

这个技巧在此前非常多篇文章中,也频繁提及过,就是利用 filter: contrast() 滤镜与 filter: blur() 滤镜。

如果你还不了解这个技巧,可以戳我的这篇文章看看:你所不知道的 CSS 滤镜技巧与细节

简述下该技巧:

单独将两个滤镜拿出来,它们的作用分别是:

  1. filter: blur(): 给图像设置高斯模糊效果。
  2. filter: contrast(): 调整图像的对比度。

但是,当他们“合体”的时候,产生了奇妙的融合现象。

仔细看两圆相交的过程,在边与边接触的时候,会产生一种边界融合的效果,通过对比度滤镜把高斯模糊的模糊边缘给干掉,利用高斯模糊实现融合效果。

基于此,我们再简单改造下我们的 CSS 代码,所需要加的代码量非常少:

  1. 加上滤镜 blur() 和 contrast() ,形成融合粘性效果
  2. 加上整个圆环的旋转即可效果
  3. 加上滤镜 hue-rotate(),实现色彩的变换动画
.g-container {
// ... 保持一致
background: #000;
filter: blur(3px) contrast(5);
animation: rotate 4s infinite linear;
}
@keyframes rotate {
100% {
transform: rotate(360deg);
filter: blur(3px) contrast(5) hue-rotate(360deg);
}
}

就这样,我们就大致还原了题图的效果:

完整的代码,你可以戳这里:CodePen Demo -- Pure CSS Loading Animation

修复违和感

当然,上面的效果,乍一看还行,仔细看,违和感很重。

原因在于,扩散出来的小球也跟着半圆环一起进行了旋转动画,看上去就有点奇怪。

正确的做法应该是,圆环尾部的气泡应该是原地发散消失的。

那么,怎么能够做到气泡效果,一直发生在圆环的尾部,同时消失的时候又不跟着整个圆环一起进行旋转呢?我们想要的最终效果,应该是这样:

这里,我们可以拆解一下。想象,如果去掉圆环的旋转,其实我们只需要实现这样一个效果即可:

整个动画的核心就转变成了如何实现这么一个效果。看似复杂,其实也很好做。

首先,我们重新改造一下上述的 .g-bubbles

  1. 生成 N 个一样大小的小球元素,定位在整个容器的中间
<div class="g-container">
<div class="g-circle"></div>
<ul class="g-bubbles">
<li class="g-bubble"></li>
// ... 共 200 个 bubble 元素
<li class="g-bubble"></li>
</ul>
</div>
.g-bubbles {
position: absolute;
width: 30px;
height: 30px;
transform: translate(-50%, -50%);
left: 50%;
top: 50%;
border-radius: 50px;
}
.g-bubble {
position: absolute;
inset: 0;
border-radius: 50%;
background: hsl(60, 75%, 40%);
}

得到这么一个效果,所有圆形小点,都暂时汇聚在容器的中心:

这里需要简单解释一下:

其次,我们借助 SASS,按照元素的顺序,把它们顺序排列到圆环轨迹之上:

$count: 200;
@for $i from 1 through $count {
.g-bubble:nth-child(#{$i}) {
--rotate: calc(#{360 / $count} * #{$i} * 1deg);
transform:
rotateZ(var(--rotate))
translate(135px, 0);
opacity: 1;
}
}

由于我们设置了 div 小球的个数为 200 个,这样,我们就得到了一圈由 200 个圆形小球形成的圆环:

接下来这一步非常重要,我们设定一个动画:

  1. 让每个小球在动画的 75% ~ 100% 阶段做透明度从 1 到 0 的变换,而 0% ~ 75% 的阶段保持透明度为 0
  2. 让 200 个 div 依次进行这个动画效果(利用负的 animation-delay,从 -0 到 -4000ms),整体上就能形成逐渐消失的效果
@for $i from 1 through $count {
.g-bubble:nth-child(#{$i}) {
--rotate: calc(#{360 / $count} * #{$i} * 1deg);
--delayTime: calc(4000 * #{$i / $count} * -1ms);
transform:
rotateZ(var(--rotate))
translate(135px, 0);
opacity: 1;
animation: showAndHide 4000ms linear var(--delayTime) infinite;
}
}
@keyframes showAndHide {
0% {
opacity: 0;
}
75% {
opacity: 0;
}
75.1% {
opacity: 1;
}
100% {
opacity: 0;
}
}

这样,我们就得到了一个圆形小球气泡围绕圆环渐次消失的效果:

配合上整个圆环,效果就会是这样:

很接近了,但是没有随机的感觉,气泡也没有散开的动画。解决的方案:

  1. 所以我们需要让气泡在执行透明度变化的同时,进行一个随机的发散位移
  2. 小圆形气泡的大小也可以带上一点随机,同时,在动画过程逐渐缩小

当然,整个动画的基础,还是在容器设置了 滤镜 blur() 和 contrast() 的加持之下的,这样,我们给气泡再补上随机动画散开及缩放的动画:

@for $i from 1 through $count {
.g-bubble:nth-child(#{$i}) {
--rotate: calc(#{360 / $count} * #{$i} * 1deg);
--delayTime: calc(4000 * #{$i / $count} * -1ms);
--scale: #{0.4 + random(10) / 10};
--x: #{-100 + random(200)}px;
--y: #{-100 + random(200)}px;
transform:
rotateZ(var(--rotate))
translate(135px, 0);
opacity: 1;
animation: showAndHide 4000ms linear var(--delayTime) infinite;
}
} @keyframes showAndHide {
0% {
transform:
rotateZ(var(--rotate))
translate(135px, 0);
opacity: 0;
}
75% {
opacity: 0;
}
75.1% {
transform:
rotateZ(var(--rotate))
translate(135px, 0)
scale(var(--scale));
opacity: 1;
}
100% {
transform:
rotateZ(var(--rotate))
translate(calc(135px + var(--x)), var(--y))
scale(.2);
opacity: 0;
}
}

只看一圈的气泡圆形,我们能得到了这样的效果:

配合上圆环的效果:

配合上父容器的 filter: hue-rotate() 动画,就能实现颜色的动态变换,得到我们最终想要的效果:

这样,没有了第一版本的违和感,整个效果也显得比较自然。

完整的代码,你可以戳这里:CodePen Demo -- Pure CSS Loading Animation

最后

好了,本文到此结束,希望对你有帮助

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

涨姿势了,有意思的气泡 Loading 效果的更多相关文章

  1. CSS content换行技术实现字符animation loading效果

    一.之前我的字符loading实现 关于字符打点动画实现,我之前使用过box-shadow模拟,还有border+background模拟,还有使用text-shadow实现,以及今年自认为是最好的实 ...

  2. 页面loading效果

    当网页太大,打开太慢的时候,为了增加良好的用户体验(不让用户眼巴巴的等,心中暗骂c,这么慢),我们需要加一个等待动画. 只需把以下代码加入页面中即可,图片可以根据自己的需求更换,更换图片之后需要改变l ...

  3. 网页Loading效果

    问题描述:由于项目要求在页面提交以及加载的时候,有短暂的卡顿,需要用loading过渡. 1.下一个页面加载的时候实现: base-loading.js //获取浏览器页面可见高度和宽度 var _P ...

  4. 一个不错的loading效果--IT蓝豹

    一个不错的loading效果 介绍:一个不错的loading加载效果,弹性收缩,效果不错,学习android动画的朋友可以下载来研究研究本例子其实由SeekBar实现,由MetaballView,Me ...

  5. DUILIB 实现微信气泡聊天效果

    最近由于项目原因,需要做一个产品内嵌的IM聊天系统.而且要象微信类似的效果:界面也要比较炫: 开始考虑用MFC,但MFC的控件自绘很麻烦,后来又考虑QT,倒是使用控件使用方便,但QT库太大,所以也放弃 ...

  6. 【转】 CSS3实现10种Loading效果

    昨晚用CSS3实现了几种常见的Loading效果,虽然很简单,但还是分享一下,顺便也当是做做笔记…… PS:如需转载,请注明出处! 第1种效果: 代码如下: <div class="l ...

  7. jQuery8种不同的瀑布流懒加载loading效果

    优化图片加载插件jQuery8种不同的瀑布流懒加载loading效果  在线预览 下载地址 实例代码 <ul class="grid effect-1" id="g ...

  8. HTML5 Canvas 实现的9个 Loading 效果

    Sonic.js 是一个很小的 JavaScript 类,用于创建基于 HTML5 画布的加载图像.更强大的是 Sonic.js 还提供了基于现成的例子的创建工具,可以帮助你实现更多自定义的(Load ...

  9. 加载状态为complete时移除loading效果

    一.JS代码: //获取浏览器页面可见高度和宽度 var _PageHeight = document.documentElement.clientHeight, _PageWidth = docum ...

  10. CSS3轻松实现清新 Loading 效果

    至今HTML5中国已经为大家分享过几百种基于 CSS3 的Loading加载动画,效果酷炫代码简洁,非常值得学习借鉴;今天就先给大家分享两个常用的CSS3的Loading的案例. 第一种效果: HTM ...

随机推荐

  1. 【转载】Fisher精确检验的通俗理解

    一直以来都很欣赏把东西讲得通俗简单的文章,今天碰巧翻到一篇, 讲Fisher检验的,内容虽然不深,但是体验很好,能感受到作者想方设法想要读者明白的那种心思~ 原文在这里: https://blog.c ...

  2. MSSQL SQL SERVER 2008 使用RowNumber()分页查询并获取总行数 附达梦数据库

    参数:pages:要查询的页码(要查询第几页):pageNum:要查询的行数(每页要查多少行):适用于使用多表查询,不以固定的实体类保存结果,如使用 List<Map<String, Ob ...

  3. 10.10 2020 实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发

    一.实验目的 熟悉 Postman 的使用:熟悉如何使用 OpenDaylight 通过 Postman 下发流表.   二.实验任务 推荐阅读:SDNLAB 文章:OpenFlow 协议超时机制简介 ...

  4. 在IDEA中通过插件显示每一行代码的最后编辑的人

    !!!首先:需要结合Git使用 插件github:https://github.com/zielu/GitToolBox/wiki/Manual 一.安装插件并重启 二.打开设置(重启默认打开) 三. ...

  5. AD域服务相关知识

    一.活动目录及意义 活动目录:windows网络中的目录服务(Directory Service),即活动目录域服务(AD DS) 目录服务:目录和与目录相关服务 活动目录负责目录数据库的保存.新建. ...

  6. [Windows] Visual Studio 类库Xml文档免费翻译工具 《Xml文档翻译器2.1》

    谷歌Chrome翻译功能失效用不了,我们一起来恢复翻译功能! 可用的谷歌国内 IP: 142.250.4.90 translate.googleapis.com 142.250.30.90 trans ...

  7. CentOS7-mysql5.7.35安装配置

    一.下载网址 注:mysql从5.7的某个版本之后之后不再提供my-default.cnf文件,不耽误启动,想要自定义配置可以自己去/etc下创建my.cnf文件 全版本:https://downlo ...

  8. java 通过反射以及MethodHandle执行泛型参数的静态方法

    开发过程中遇到一个不能直接调用泛型工具类的方法,因此需要通过反射来摆脱直接依赖. 被调用静态方法示例 public class test{ public static <T> T get( ...

  9. AbstractRoutingDataSource - 动态数据源

    AbstractRoutingDataSource 类说明: (1)它的抽象方法 determineCurrentLookupKey() 决定使用哪个数据源. (2)项目启动时,先调用 setTarg ...

  10. IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

    代码: cate_ids=np.unique(gt_box_array[:,-1]) for tmp_cateid in cate_ids:       conf_matrix[tmp_cateid, ...