Amazing!!CSS 也能实现极光?

简介: Amazing!!CSS 也能实现极光?

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


像是这样:

46e0f8b08f2f49d2b8bd004c6824df9e_tplv-k3u1fbpfcp-watermark.png


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 之后,我们能够得到这样一幅夜空背景图:

4928a3a9bb5d4ec7b262e88713abd848_tplv-k3u1fbpfcp-zoom-1.png

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%
    );
}

ea4eea93d3f94b6e9f7859578faec888_tplv-k3u1fbpfcp-zoom-1.png


Step 3. 旋转拉伸



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


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


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

b27854f3a6bf44809a54578797dec4d4_tplv-k3u1fbpfcp-zoom-1.png


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



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


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


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

3fa82acef0ce439a8d6a5bfc4d29260d_tplv-k3u1fbpfcp-zoom-1.png


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


Step 5. 叠加 SVG feturbulence 滤镜



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



回归正题。我们添加一个 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>
HTML 复制 全屏


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


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

c9bda75f29e34ad781a24847ec727608_tplv-k3u1fbpfcp-zoom-1.png

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);


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


image.png


一些技巧及其他事项



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


最终的效果,不太完美,但也算一副不错的 CSS + SVG 作品。完整的代码,你可以看这里:


CodePen Demo -- Aurora

目录
相关文章
|
前端开发 JavaScript 开发者
利用 SplitingJS 配合 CSS 实现文字&quot;蠕动&quot;效果
利用 SplitingJS 配合 CSS 实现文字&quot;蠕动&quot;效果
377 2
|
前端开发 容器
面试官:请使用 CSS 实现自适应正方形
面试官:请使用 CSS 实现自适应正方形
501 0
面试官:请使用 CSS 实现自适应正方形
|
JavaScript 前端开发
CSS进阶向--配合Vue动态样式实现“超炫酷”圆环菜单
CSS进阶向--配合Vue动态样式实现“超炫酷”圆环菜单
891 2
CSS进阶向--配合Vue动态样式实现“超炫酷”圆环菜单
|
前端开发 JavaScript
CSS进阶向--纯css实现流光边框(二)
CSS进阶向--纯css实现流光边框(二)
2301 1
CSS进阶向--纯css实现流光边框(二)
|
前端开发 容器
我已经说了5种css居中实现的方式了,面试官竟然说还不够?
这是一篇关于居中对齐方式的总结 开篇之前,先问一下大家都知道几种居中的实现方式? 面试时答出来两三个就不错了,就怕面试官还让你继续说。今天就来总结一下这些居中的方式 使用flex布局设置居中。 使用flex 时也能通过给子项设置margin: auto实现居中。 使用绝对定位的方式实现水平垂直居中。 使用grid设置居中。 使用grid时还能通过给子项设置margin: auto实现居中。 使用tabel-cell实现垂直居中。 还有一种不常用的方法实现垂直居中。 最后还有一种奇葩的方法。容器设置position: relative。孩子设置 top、left、bottom、right都设
172 0
我已经说了5种css居中实现的方式了,面试官竟然说还不够?
|
前端开发
HTML+CSS实现商品介绍模考(以Apple14为案例)
本文以最通俗易懂的语言为读者提供一个经典CSS小案例,商品介绍模块,并且结合时事,以Apple14为案例进行讲解。
181 0
HTML+CSS实现商品介绍模考(以Apple14为案例)
|
前端开发 JavaScript Windows
js实现body背景图自动扩缩 光靠css几乎无法实现这样的效果
js实现body背景图自动扩缩 光靠css几乎无法实现这样的效果
196 0
js实现body背景图自动扩缩 光靠css几乎无法实现这样的效果
|
前端开发
css实现弧形边框
css实现弧形边框
471 0
css实现弧形边框
|
前端开发 开发工具
教你用HTML+CSS实现百叶窗动画效果
我们浏览网页的时候总能看见一些炫酷的特效,比如百叶窗效果,本文我们就用HTML+CSS制作一个百叶窗小项目,适合刚学前端的小伙伴,使用代码简单易懂,很容易上手,学习完本文后,相信你也能敲出来属于自己的百叶窗效果,改变图片及相应盒子的大小,有女朋友的可以试着放几张在一起的照片,也是一件非常浪漫的事
559 0
教你用HTML+CSS实现百叶窗动画效果
|
移动开发 前端开发 小程序
【笔记】纯css实现列表水平滑动(图片或文字内容不限)
纯css实现列表水平滑动(图片或文字内容不限)
309 0