关于前端:AmazingCSS-也能实现极光

3次阅读

共计 3109 个字符,预计需要花费 8 分钟才能阅读完成。

在上次写完这篇文章 — 巧用突变实现高级感拉满的背景光动画 之后,文章上面的评论有同学留言,应用 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;
}

神奇的事件产生了,看看成果:

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

Step 5. 叠加 SVG feturbulence 滤镜

接下来,咱们要产生水纹稳定的成果,须要借助 SVG 的 <feturbulence> 滤镜,对这个滤镜还不太理解的,能够看看我的这几篇文章:

  • 有意思!弱小的 SVG 滤镜
  • 震惊!巧用 SVG 滤镜还能制作表情包?
  • 实现一个会动的鸿蒙 LOGO

回归正题。咱们增加一个 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);

至此,咱们就失去了一幅残缺的,会动的极光动画:

一些技巧及其他事项

  1. 突变元素的四周会存在显著的边界毛刺成果,能够应用彩色内暗影 box-shadow: inset ... 去除;
  2. 理论行文过程中的各个属性的理论参数看似简略,过程中其实通过了一直的调试才失去;
  3. 混合模式及 SVG 的 feturbulence 滤镜比拟难把握,须要一直的练习,一直的调试;本文极光的色彩选取没有通过太多重复调试,违心花工夫,能够调试出成果更好的色彩。

最终的成果,不太完满,但也算一副不错的 CSS + SVG 作品。残缺的代码,你能够看这里:

CodePen Demo — Aurora

最初

好了,本文到此结束,心愿本文对你有所帮忙 :)

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 😄

更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。

如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。

正文完
 0