zoukankan      html  css  js  c++  java
  • Amazing!!CSS 也能实现极光?

    在上次写完这篇文章 -- 巧用渐变实现高级感拉满的背景光动画 之后,文章下面的评论有同学留言,使用 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;
         350px;
        height: 500px;
        background: #0b1a3a;
        overflow: hidden;
        
        &::before {
            content: "";
            position: absolute;
             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 {
         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 的 <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

    最后

    好了,本文到此结束,希望本文对你有所帮助

    更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

    如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

  • 相关阅读:
    SpringBoot使用Swagger2实现Restful API
    SpringBoot返回json和xml
    SpringBoot定时任务
    SpringBoot+Jpa+MySql学习
    SpringBoot+Mybatis+MySql学习
    linux安装jdk
    linux下安装mysql
    利用nginx,腾讯云免费证书制作https
    SpringBoot使用数据库
    SpringBoot的国际化使用
  • 原文地址:https://www.cnblogs.com/coco1s/p/15722286.html
Copyright © 2011-2022 走看看