이 글에서는 CSS3애니메이션에 대해 이야기하고 순수한 CSS를 사용하여 매우 멋진 끈적이는 거품 효과를 얻는 방법을 살펴보겠습니다. 이 글이 모든 사람에게 도움이 되기를 바랍니다.
최근 CodePen에서 다음과 같은 흥미로운 효과를 보았습니다.
이 효과의 핵심 난이도는 거품의 특별한 융합 효과에 있습니다. [추천 학습: css 비디오 튜토리얼]
소스 코드는 CodePen Demo -- Goey footer에 있습니다. 저자는 이 효과를 얻기 위해 주로 SVG 필터를 사용합니다. 관심이 있다면 소스를 클릭하세요. 살펴보는 코드입니다.
그 중에서도 SVG에서 feGaussianBlur
필터를 유연하게 사용하려면 여전히 매우 강력한 SVG 지식 기반이 필요합니다. 그렇다면 CSS만으로 이 효과를 얻을 수 있을까요? feGaussianBlur
滤镜还是需要有非常强大的 SVG 知识储备的。那么,仅仅使用 CSS 能否实现该效果呢?
嘿嘿,强大的 CSS 当然是可以的。本文,就将带领大家一步步使用纯 CSS,完成上述效果。
首先,如果上述效果没有气泡的融合效果,可能就仅仅是这样:
要制作这样一个效果还是比较简单的,只是代码会比较多,我们借助 SASS 预处理器即可。
假设我们有如下 HTML 结构:
<div class="g-wrap"> <div class="g-footer"> <div class="g-bubble"></div> <div class="g-bubble"></div> // ... 200 个 g-bubble </div> </div>
核心要做的,仅仅是让 200 个 .g-bubble
从底部无规律的进行向上升起的动画。
这里,就需要运用一种技巧 -- 利用 animation-duration 和 animation-delay 构建随机效果。
同一个动画,我们利用一定范围内随机的 animation-duration
和一定范围内随机的 animation-delay
,可以有效的构建更为随机的动画效果,让动画更加的自然。
我们来模拟一下,如果是使用 10 个 animation-duration
和 animation-delay
都一致的圆的话,核心伪代码:
<ul> <li></li> <!--共 10 个...--> <li></li> </ul>
ul { display: flex; flex-wrap: nowrap; gap: 5px; } li { background: #000; animation: move 3s infinite 1s linear; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(0, -100px); } }
这样,小球的运动会是这样的整齐划一:
要让小球的运动显得非常的随机,只需要让 animation-duration
和 animation-delay
都在一定范围内浮动即可,改造下 CSS:
@for $i from 1 to 11 { li:nth-child(#{$i}) { animation-duration: #{random(2000)/1000 + 2}s; animation-delay: #{random(1000)/1000 + 1}s; } }
我们利用 SASS 的循环和 random()
函数,让 animation-duration
在 2-4 秒范围内随机,让 animation-delay
在 1-2 秒范围内随机,这样,我们就可以得到非常自然且不同的上升动画效果,基本不会出现重复的画面,很好的模拟了随机效果:
CodePen Demo -- 利用范围随机 animation-duration 和 animation-delay 实现随机动画效果
好,我们把上述介绍的技巧,套用到我们本文要实现的效果中去,HTML 结构再看一眼:
<div class="g-wrap"> <div class="g-footer"> <div class="g-bubble"></div> <div class="g-bubble"></div> // ... 200 个 g-bubble </div> </div>
核心的 CSS 代码:
.g-footer { position: absolute; bottom: 0; left: 0; height: 86px; width: 100%; background: #26b4f5; } @for $i from 0 through 200 { .g-bubble:nth-child(#{$i}) { position: absolute; background: #26b4f5; $width: random(100) + px; left: #{(random(100)) + '%'}; top: #{(random(100))}px; width: $width; height: $width; animation: moveToTop #{(random(2500) + 1500) / 1000}s ease-in-out -#{random(5000)/1000}s infinite; } } @keyframes moveToTop { 90% { opacity: 1; } 100% { opacity: .08; transform: translate(-50%, -180px) scale(.3); } }
这里:
我们利用了 SASS 随机函数 $width: random(100) + px;
,随机生成不同大小的 div 圆形
利用 SASS 随机函数 left: #{(random(100)) + '%'}
,top: #{(random(100))}px
基于父元素随机定位
最为核心的是 animation: moveToTop #{(random(2500) + 1500) / 1000}s ease-in-out -#{random(5000)/1000}s infinite
이렇게 만들려면 하나의 효과는 비교적 간단하지만 코드가 더 많아집니다. SASS 전처리기를 사용할 수 있습니다.
🎜다음과 같은 HTML 구조가 있다고 가정해 보겠습니다. 🎜.g-wrap { background: #fff; filter: contrast(8); } .g-footer { // ... 其他保持一致 filter: blur(5px); }
.g-bubble
을 애니메이션화하는 것뿐입니다. 🎜🎜여기서 애니메이션 지속 시간과 애니메이션 지연을 사용하여 무작위 효과를 구축하는 기술을 사용해야 합니다. 🎜animation-duration
과 특정 Random을 사용합니다. 범위 내의 animation-delay
는 보다 무작위적인 애니메이션 효과를 효과적으로 구축하고 애니메이션을 더욱 자연스럽게 만들 수 있습니다. 🎜🎜동일한 animation-duration
및 animation-delay
를 사용하여 10개의 원을 사용하면 핵심 의사 코드는 다음과 같습니다. 🎜.g-footer { // ... filter: blur(5px); }
.g-footer { // ... 去掉 filter: blur(5px) &:before { content: ""; position: absolute; top: -300px; left: 0; right: 0; bottom: 0; z-index: 1; backdrop-filter: blur(5px); } }
animation-duration
및 animation-delay code>를 설정하세요. CSS를 변환합니다. 🎜rrreee🎜SASS 루프와 <code>random()
함수를 사용하여 animation-duration
을 2에서 무작위로 만듭니다. 4초 범위에서 animation-delay
를 1~2초 범위 내에서 무작위로 지정하면 매우 자연스럽고 다른 상승 애니메이션 효과를 얻을 수 있으며 기본적으로 반복이 발생하지 않습니다. 그림. 무작위 효과의 좋은 시뮬레이션: 🎜🎜🎜🎜🎜🎜CodePen 데모 -- 범위 무작위 애니메이션 사용 - 지속 시간 및 애니메이션 지연으로 인해 임의의 애니메이션 효과를 얻을 수 있습니다. 🎜🎜🎜 좋습니다. 위에서 소개한 기술을 이 기사에서 달성하려는 효과에 적용해 보겠습니다. HTML 구조를 다시 살펴보겠습니다. 🎜rrreee🎜핵심 CSS 코드: 🎜rrreee🎜 여기 :🎜$width:random(100) + px;
를 사용하여 다양한 크기를 무작위로 생성합니다. div Circle🎜🎜left: #{(random(100)) + '%'}
, top: #{(random(100))} px
는 상위 요소를 기준으로 무작위로 배치됩니다🎜🎜애니메이션입니다: moveToTop #{(random(2500) + 1500) / 1000}seasy-in-out -#{random ( 5000)/1000}은 무한
이므로 모든 div 원의 움직임은 무작위입니다🎜🎜🎜🎜위 (1)과 (2)의 결합 결과는 원이 고르게 분산된 레이아웃을 생성합니다. 모양: 🎜🎜🎜🎜🎜🎜注:这里为了方便理解,我隐藏了最外层g-footer
的颜色,并且给g-bubble
添加了黑色边框
接着,如果我们替换一下 animation
语句,使用统一的动画时长,去掉负的延迟,变成 animation: moveToTop 4s ease-in-out infinite
,动画就会是这样:
整体是整齐划一,没有杂乱无章的感觉的。
运用上随机效果,animation: moveToTop #{(random(2500) + 1500) / 1000}s ease-in-out -#{random(5000)/1000}s infinite
,就能得到上述的,不同气泡随机上升的感觉:
接下来,也是最重要的一步,如何让气泡与气泡之间,以及气泡和底部 .g-footer
之间产生融合效果呢?
这个技巧在此前非常多篇文章中,也频繁提及过,就是利用 filter: contrast()
滤镜与 filter: blur()
滤镜。
如果你还不了解这个技巧,可以戳我的这篇文章看看:你所不知道的 CSS 滤镜技巧与细节
简述下该技巧:
单独将两个滤镜拿出来,它们的作用分别是:
filter: blur()
: 给图像设置高斯模糊效果。
filter: contrast()
: 调整图像的对比度。
但是,当他们“合体”的时候,产生了奇妙的融合现象。
仔细看两圆相交的过程,在边与边接触的时候,会产生一种边界融合的效果,通过对比度滤镜把高斯模糊的模糊边缘给干掉,利用高斯模糊实现融合效果。
基于此,我们再简单改造下我们的 CSS 代码,所需要加的代码量非常少:
.g-wrap { background: #fff; filter: contrast(8); } .g-footer { // ... 其他保持一致 filter: blur(5px); }
就这么简单,父容器添加白色底色以及对比度滤镜 filter: contrast(8)
,子容器添加 filter: blur(5px)
即可,这样,我们就能得气泡的融合效果,基本得到我们想要的效果:
但是!利用 filter: blur()
会有一个小问题。
运用了 filter: blur()
的元素,元素边缘的模糊度不够,会导致效果在边缘失真,我们仔细看看动画的边缘:
如何解决呢?也好办,在这里,我们尝试利用 backdrop-filter
去替换 filter
。
两者之间的差异在于,filter
是作用于元素本身,而 backdrop-filter
是作用于元素背后的区域所覆盖的所有元素。
简单改造下代码,原代码:
.g-footer { // ... filter: blur(5px); }
改造后的代码:
.g-footer { // ... 去掉 filter: blur(5px) &:before { content: ""; position: absolute; top: -300px; left: 0; right: 0; bottom: 0; z-index: 1; backdrop-filter: blur(5px); } }
我们通过去到原来添加在 .g-footer
上的 filter: blur(5px)
,通过他的伪元素,叠加一层新的元素在它本身之上,并且添加了替代的 backdrop-filter: blur(5px)
。
当然,因为这里的 blur(5px)
还需要为气泡与气泡之间的融合服务,所以为了覆盖动画全区域,我们还设置了 top: -300px
,扩大了它的作用范围。
最终,我们就能完美的复刻文章一开头,使用 SVG 滤镜实现的效果:
在文章中,我省去了大部分基础的 CSS 代码,完整的代码,你可以戳这里:CodePen Demo -- Bubble Rises
(学习视频分享:web前端入门)
위 내용은 실제 CSS3 애니메이션: 매우 멋진 끈적이는 버블 효과의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!