在上次写完 巧用渐变实现高级感拉满的背景光动画[1] 之后,文章下面的评论有同学留言,使用 CSS 可以实现极光吗?,下面我们就来说一说关于看一下前端的显示方式?我们一起去了解并探讨一下这个问题吧!

看一下前端的显示方式(AmazingCSS)

看一下前端的显示方式

在上次写完 巧用渐变实现高级感拉满的背景光动画[1] 之后,文章下面的评论有同学留言,使用 CSS 可以实现极光吗

像是这样:

emmm,这有点难为人了。不过,最近我也尝试着去试了下,虽然不可能模拟出那么真实的效果,但是使用 CSS 还是可以作出类似的一些特效的,今天我们就一起来尝试下。

观察了一些极光的图片之后,我发现了极光动画中一些比较重要的元素:

  1. 基于深色背景的明亮渐变色彩

  2. 类似于水波流动的动画效果

明亮渐变色彩我们可以尽量使用 渐变 模拟。而水波流动的动画效果,在 SVG 滤镜中 feturbulence 就是专门干这个的,这个滤镜的使用在我过去的多篇文章中也有反复的提及过。

而除了渐变、SVG 的 <feturbulence> 滤镜之外,我们可能还会用到混合模式(mix-blend-mode)、CSS 滤镜等提升效果。

OK,有了大概的思路后,剩下的就是不断的尝试。

Step 1. 绘制深色背景

首先,我们可能需要一个深色的背景,用于表示我们的夜空。同时点缀一些星星,星星可以使用 box-shadow 模拟,这样,一副夜空背景我们可以在 1 个 div 内完成:

<div class="g-wrap"> </div>

@function randomNum($max, $min: 0, $u: 1) { @return ($min random($max)) * $u; } @function shadowSet($n, $size) { $shadow : 0 0 0 0 #fff; @for $i from 0 through $n { $x: randomNum(350); $y: randomNum(500); $scale: randomNum($size) / 10; $shadow: $shadow, #{$x}px #{$y}px 0 #{$scale}px rgba(255, 255, 255, .8); } @return $shadow; } .g-wrap { position: relative; width: 350px; height: 500px; background: #0b1a3a; overflow: hidden; &::before { content: ""; position: absolute; width: 1px; height: 1px; border-radius: 50%; box-shadow: shadowSet(100, 6); }

这一步比较简单,借助了 SASS 之后,我们能够得到这样一幅夜空背景图:

Step 2. 使用渐变画出极光的轮廓

接下来,就是利用渐变,画出极光的一个轮廓效果。

其实就是一个径向渐变:

<div class="g-wrap"> <div class="g-aurora"></div> </div>

.g-aurora { width: 400px; height: 300px; background: radial-gradient( circle at 100% 100%, transparent 45%, #bd63c1 55%, #53e5a6 65%, transparent 85% ); }

Step 3. 旋转拉伸

目前看来,是有一点点轮廓了。下一步,我们把得到的这个渐变效果通过旋转拉伸变换一下。

.g-aurora { ... transform: rotate(45deg) scaleX(1.4); }

我们大概就能得到这样一个效果:

Step 4. 神奇的混合模式变换!

到这里,其实雏形已经出来了。但是颜色看着不太像,为了和深色的背景融合在一起,这里我们运用上混合模式 mix-blend-mode。

.g-aurora { ... transform: rotate(45deg) scaleX(1.4); mix-blend-mode: color-dodge; }

神奇的事情发生了,看看效果:

image

整体的颜色看上去更加像极光的颜色。

Step 5. 叠加 SVG feturbulence 滤镜

接下来,我们要产生水纹波动的效果,需要借助 SVG 的 <feturbulence> 滤镜,对这个滤镜还不太了解的,可以看看我的这几篇文章:

  • 有意思!强大的 SVG 滤镜[2]

  • 震惊!巧用 SVG 滤镜还能制作表情包?[3]

  • 实现一个会动的鸿蒙 LOGO[4]

    回归正题。我们添加一个 SVG 的 <feturbulence> 滤镜,利用 CSS filter 进行引用

    <div class="g-wrap"> <div class="g-aurora"></div> </div> <svg id='blob' version='1.1' xmlns='http://www.w3.org/2000/svg'> <defs> <filter id='wave'> <feturbulence basefrequency='0.003 0.003 id='turbulence' numoctaves='3' result='noise' seed='10' /> <fedisplacementmap id='displacement' in2='noise' in='SourceGraphic' scale='96' /> </filter> </defs> </svg>

    .g-aurora { ... transform: rotate(45deg) scaleX(1.4); mix-blend-mode: color-dodge; filter: url(#wave); }

    我们即可得到这样一种效果:

    Wow,是不是已经很有那种感觉了。通过 feturbulence 的特性,我们近乎模拟出了极光的效果!

    Step 6. 让极光动起来

    最后一步,我们就需要让我们的极光动起来。由于 SVG 动画本身不支持类似 animation-fill-mode: alternate 这种特性。我们还是需要写一点 JavaScript 代码,控制动画的整体循环。

    大概的代码是这样:

    var filter = document.querySelector("#turbulence"); var frames = 0; var rad = Math.PI / 180; function freqAnimation() { bfx = 0.005; bfy = 0.005; frames = .5 bfx = 0.0025 * Math.cos(frames * rad); bfy = 0.0025 * Math.sin(frames * rad); bf = bfx.toString() ' ' bfy.toString(); filter.setAttributeNS(null, 'baseFrequency', bf); window.requestAnimationFrame(freqAnimation); } window.requestAnimationFrame(freqAnimation);

    至此,我们就得到了一幅完整的,会动的极光动画: