当前位置: 首页 > 科技观察

精彩的!超酷的泡泡效果

时间:2023-03-19 11:24:01 科技观察

最近在CodePen上看到这样一个非常有趣的效果:这个效果的核心难点在于一个特殊的泡泡融合效果。其源代码位于:CodePenDemo--Goeyfooter[1]。作者主要使用SVG滤镜来完成这个效果。有兴趣的可以查看源码。其中,要想在SVG中灵活使用feGaussianBlur滤镜,还是需要非常强大的SVG知识储备。那么,是否可以仅使用CSS来实现这种效果呢?嘿,强大的CSS当然是可以的。本文将带领大家一步步使用纯CSS实现上述效果。使用SASS完成一般效果首先,如果上面的效果没有气泡的融合效果,可能只是这样:做这样的效果比较简单,但是代码会比较多,我们可以使用SASS预处理器。假设我们有以下HTML结构:

//...200个g-bubbles
核心要做的就是让200个.g-bubbles从底部不规则的往上冒。在这里,我们需要用到我们在CSS动画[2]一文中介绍的技术——使用animation-duration和animation-delay来构建随机效果。使用animation-duration和animation-delay来构建一个具有相同动画的随机动画,我们使用一定范围内的randomanimation-duration和一定范围内的randomanimation-delay来有效构建出更加随机的动画效果,让动画更加自然。我们来模拟一下,如果我们用10个animation-duration和animation-delay都一样的圆,核心伪代码:ul{显示:flex;弹性包装:nowrap;间隙:5px;}li{背景:#000;动画:移动3s无限1s线性;}@keyframesmove{0%{transform:translate(0,0);}100%{转换:翻译(0,-100px);}}这样小球的运动就会很均匀:要让小球的运动非常随机,只需要让animation-duration和animation-delay都在一定范围内浮动,修改CSS即可:@对于$i从1到11{li:nth-child(#{$i}){animation-duration:#{random(2000)/1000+2}s;动画延迟:#{random(1000)/1000+1}s;}}我们使用SASS循环和random()函数让animation-duration在2-4秒范围内随机化,让animation-delay在1-2秒范围内随机化,这样我们就可以得到非常自然和不同的上升动画效果,基本不会出现重复画面,随机效果模拟的很好:CodePenDemo--使用rangerandomanimation-duration和animation-delay实现随机动画效果[3]。好了,我们把上面介绍的技巧应用到本文想要达到的效果上,再看一下HTML结构://...200g-bubbles核心CSS代码:.g-页脚{位置:绝对;底部:0;左:0;高度:86px;宽度:100%;背景:#26b4f5;}@for$i从0到200{.g-bubble:nth-child(#{$i}){position:absolute;背景:#26b4f5;$宽度:随机(100)+像素;左:#{(random(100))+'%'};顶部:#{(random(100))}px;宽度:$宽度;高度:$宽度;动画:moveToTop#{(random(2500)+1500)/1000}sease-in-out-#{random(5000)/1000}sinfinite;}}@关键帧moveToTop{90%{不透明度:1;}100%{不透明度:0.08;变换:平移(-50%,-180px)比例(.3);}}这里:我们使用SASS的随机函数$width:random(100)+px;,随机生成不同大小的div圆圈。使用SASS随机函数left:#{(random(100))+'%'},top:#{(random(100))}px根据父元素随机定位。核心是动画:moveToTop#{(random(2500)+1500)/1000}sease-in-out-#{random(5000)/1000}s无穷大,让所有div圈的移动都是随机的。上面(1)和(2)的组合结果会生成这样的布局,均匀分布的圆圈:注:为了方便理解,我隐藏了最外层g-footer的颜色,给g-bubble加了黑边.那么,如果我们替换动画语句,使用统一的动画时长,去掉负延迟,改成动画:moveToTop4sease-in-outinfinite,动画会是这样的:整体整齐划一,没有混乱的感觉。使用随机效果,动画:moveToTop#{(random(2500)+1500)/1000}sease-in-out-#{random(5000)/1000}sinfinite,可以得到如上,不同的气泡随机上升感受:添加融合效果接下来最重要的一步就是如何制作气泡与气泡之间、气泡与底部.g-footer之间的融合效果?这个技巧在之前的很多文章中都经常提到,就是使用滤镜:contrast()滤镜和滤镜:blur()滤镜。如果你还不知道这个技巧,可以戳我的文章看:你不知道的CSS滤镜技巧及细节[4]。技巧简述:分别取出两个滤镜,它们的作用是:filter:blur():给图像设置高斯模糊效果。filter:contrast():调整图像的对比度。然而,当它们“合体”时,却发生了奇妙的融合现象。仔细看两个圆相交的过程。当边缘相互接触时,会产生边界融合效应。通过contrastfilter消除高斯模糊的模糊边缘,利用高斯模糊达到融合效果。基于此,我们简单修改我们的CSS代码,需要添加的代码量非常少:.g-wrap{background:#fff;filter:contrast(8);}.g-footer{//...Otherskeepthesamefilter:blur(5px);}就这么简单,给父级添加白色背景色和对比滤镜filter:contrast(8)container,在子容器中添加filter:blur(5px),这样我们就可以得到气泡的融合效果,基本上就得到了我们想要的效果:使用backdrop-filter代替filter来消除边缘但是!过滤器有一个小问题:blur()。使用filter:blur()的元素在元素的边缘模糊不够,会导致效果在边缘扭曲。让我们仔细看看动画的边缘:如何解决?这很容易做到,在这里,我们尝试使用backdrop-filter来替换滤镜。两者的区别在于filter作用于元素本身,而backdrop-filter作用于元素后面区域覆盖的所有元素。如果你想了解更多关于backdrop-filter的知识,可以点击这里文章:深入探讨filter和backdrop-filter的异同[5]。简单修改一下代码,原代码:.g-footer{//...filter:blur(5px);}修改后的代码:.g-footer{//...removefilter:blur(5px)&:在{内容:“”之前;位置:绝对;顶部:-300px;左:0;右:0;底部:0;z-索引:1;背景滤镜:模糊(5px);filter:blur(5px)添加到.g-footer,通过它的伪元素,在其自身之上覆盖一个新元素,并添加替换backdrop-filter:blur(5px)。当然,因为这里的blur(5px)也需要服务于气泡之间的融合,所以为了覆盖动画的整个区域,我们还设置了top:-300px来扩大它的作用范围。最终,我们可以完美复现文章开头使用SVG滤镜实现的效果:文中我省略了大部分基本的CSS代码,完整代码可以点这里:CodePenDemo--Bubble上升[6]。最后,这篇文章和之前熟练使用CSS实现炫酷充电动画[7]的技巧很相似,不过这篇文章也有一些新的知识点,大家可以一起看看。好了,本文到此结束,希望对你有所帮助:)参考[1]CodePenDemo--Goeyfooter:https://codepen.io/z-/pen/zYxdRQy。[2]简单的CSS动画:https://github.com/chokcoco/iCSS/issues/141。[3]CodePenDemo——使用rangerandomanimation-duration和animation-delay实现随机动画效果:https://codepen.io/Chokcoco/pen/JjyRYyR。[4]你不知道的CSS过滤技巧和细节:https://github.com/chokcoco/iCSS/issues/30。[5]深入探讨filter和backdrop-filter的异同:https://github.com/chokcoco/iCSS/issues/147。[6]CodePen演示——气泡上升:https://codepen.io/Chokcoco/pen/QWQRjrX。[7]使用CSS实现炫酷的充电动画:https://github.com/chokcoco/iCSS/issues/75。