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

  1. 基于深色背景的明亮渐变色彩
  2. 类似于水波流动的动画效果

明亮渐变色彩可以尽量使用 渐变 模拟。而水波流动的动画效果,在 SVG 滤镜中 feturbulence 就是专门干这个的。
而除了渐变、SVG 的 <feturbulence> 滤镜之外,可能还会用到混合模式mix-blend-mode)、CSS 滤镜等提升效果。
有了大概的思路后,剩下的就是不断的尝试。

Step 1. 绘制深色背景

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

  1. <div class="g-wrap">
  2. </div>
  1. @function randomNum($max, $min: 0, $u: 1) {
  2. @return ($min + random($max)) * $u;
  3. }
  4. @function shadowSet($n, $size) {
  5. $shadow : 0 0 0 0 #fff;
  6. @for $i from 0 through $n {
  7. $x: randomNum(350);
  8. $y: randomNum(500);
  9. $scale: randomNum($size) / 10;
  10. $shadow: $shadow, #{$x}px #{$y}px 0 #{$scale}px rgba(255, 255, 255, .8);
  11. }
  12. @return $shadow;
  13. }
  14. .g-wrap {
  15. position: relative;
  16. width: 350px;
  17. height: 500px;
  18. background: #0b1a3a;
  19. overflow: hidden;
  20. &::before {
  21. content: "";
  22. position: absolute;
  23. width: 1px;
  24. height: 1px;
  25. border-radius: 50%;
  26. box-shadow: shadowSet(100, 6);
  27. }

这一步比较简单,借助了 SASS 之后,能够得到这样一幅夜空背景图:
CSS 实现极光特效 - 图1

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

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

  1. <div class="g-wrap">
  2. <div class="g-aurora"></div>
  3. </div>
  1. .g-aurora {
  2. width: 400px;
  3. height: 300px;
  4. background: radial-gradient(
  5. circle at 100% 100%,
  6. transparent 45%,
  7. #bd63c1 55%,
  8. #53e5a6 65%,
  9. transparent 85%
  10. );
  11. }

CSS 实现极光特效 - 图2

Step 3. 旋转拉伸

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

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

大概就能得到这样一个效果:
CSS 实现极光特效 - 图3

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

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

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

神奇的事情发生了,看看效果:
CSS 实现极光特效 - 图4
整体的颜色看上去更加像极光的颜色。

Step 5. 叠加 SVG feturbulence 滤镜

接下来,要产生水纹波动的效果,需要借助 SVG 的 <feturbulence> 滤镜。
添加一个 SVG 的 <feturbulence> 滤镜,利用 CSS filter 进行引用

  1. <div class="g-wrap">
  2. <div class="g-aurora"></div>
  3. </div>
  4. <svg id='blob' version='1.1' xmlns='http://www.w3.org/2000/svg'>
  5. <defs>
  6. <filter id='wave'>
  7. <feturbulence basefrequency='0.003 0.003' id='turbulence' numoctaves='3' result='noise' seed='10' />
  8. <fedisplacementmap id='displacement' in2='noise' in='SourceGraphic' scale='96' />
  9. </filter>
  10. </defs>
  11. </svg>
  1. .g-aurora {
  2. ...
  3. transform: rotate(45deg) scaleX(1.4);
  4. mix-blend-mode: color-dodge;
  5. filter: url(#wave);
  6. }

即可得到这样一种效果:
CSS 实现极光特效 - 图5
通过 feturbulence 的特性,近乎模拟出了极光的效果!

Step 6. 让极光动起来

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

  1. var filter = document.querySelector("#turbulence");
  2. var frames = 0;
  3. var rad = Math.PI / 180;
  4. function freqAnimation() {
  5. bfx = 0.005;
  6. bfy = 0.005;
  7. frames += .5
  8. bfx += 0.0025 * Math.cos(frames * rad);
  9. bfy += 0.0025 * Math.sin(frames * rad);
  10. bf = bfx.toString() + ' ' + bfy.toString();
  11. filter.setAttributeNS(null, 'baseFrequency', bf);
  12. window.requestAnimationFrame(freqAnimation);
  13. }
  14. window.requestAnimationFrame(freqAnimation);

至此,就得到了一幅完整的,会动的极光动画:
CSS 实现极光特效 - 图6

一些技巧及其他事项

  1. 渐变元素的周围会存在明显的边界毛刺效果,可以使用黑色内阴影 box-shadow: inset ... 去除;
  2. 实际行文过程中的各个属性的实际参数看似简单,过程中其实经过了不断的调试才得到;
  3. 混合模式及 SVG 的 feturbulence 滤镜比较难掌握,需要不断的练习,不断的调试;本文极光的颜色选取没有经过太多反复调试,愿意花时间,可以调试出效果更好的颜色。