• LPL Ban/Pick 选人阶段的遮罩效果是如何实现的?


    最近 S11 LPL 春季赛开赛,在看比赛的过程中,我发现新赛季的 Ban/Pick 选人阶段,出现了一种新的,有意思的遮罩效果,如下图所示:

    当然,它是一个动态的效果,当选人的过程中,会有一种呼吸的效果:

    Gif 图有点糊,总的而言,就是一种接近迷雾的遮罩效果。并且,他是能够动态变化的。

    本文将探究,在 CSS 中,我们应该如何去实现类似的效果。

    实现烟雾化遮罩效果

    首先,我们来尝试实现这样一个动态遮罩:

    bbg1.gif

    假设没有模糊的边缘,及烟雾化的效果,它其实就是一个渐变:

    <div></div>
    
    div {
        width: 340px;
        height: 180px;
        border: 2px solid #5b595b;
        background: linear-gradient(
            rgba(229, 23, 49, 1),
            rgba(229, 23, 49, .9) 48%,
            transparent 55%,
        );
    }
    

    经由上述代码,我们可得到:

    好吧,看着确实平平无奇,我们如何利用它,得到一个雾化的效果呢?

    提到烟雾,聪明的同学应该能想到滤镜,当然,是 SVG 的 <feturbulence> 滤镜。

    没错,又是它,<feturbulence> 确实太有意思了,我最近的两篇关于它的文章 -- Amazing!!CSS 也能实现烟雾效果?Amazing!!CSS 也能实现极光? 可以一并阅读。

    <feturbulence>type="fractalNoise" 在模拟云雾效果时非常好用。该滤镜利用 Perlin 噪声函数创建了一个图像,能够实现半透明的烟熏或波状图像,用于实现一些特殊的纹理。

    这里,我们利用 <feturbulence> 滤镜简单处理一下上述图形:

    <div></div>
    
    <svg width="0">
      <filter id="filter">
        <feTurbulence id="turbulence" type="fractalNoise" baseFrequency=".03" numOctaves="20" />
        <feDisplacementMap in="SourceGraphic" scale="30" />
      </filter>
    </svg>
    

    CSS 中,可以利用 filter: url() 对对应的元素引入该滤镜:

    div {
        ...
        filter: url(#smoke);
    }
    

    作用了滤镜的元素的效果:

    由于我给元素加了边框,整个边框也被雾化了,这不是我们想要的,可以使用伪元素改造一下,边框作用于容器,使用伪元素实现渐变,将滤镜作用于伪元素

    div {
        position: relative;
        width: 340px;
        height: 180px;
        border: 2px solid #5b595b;
        
        &::before {
            content: "";
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(
                30deg,
                rgba(229, 23, 49, 1),
                rgba(229, 23, 49, .9) 48%,
                transparent 55%,
            );
            filter: url(#smoke);
        }
    }
    

    改造后的效果如下:

    好,又接近了一步,但是四周有很多瑕疵没有被填满。问题不大,我们改变一下定位的 top \ left \ right \ bottom,让伪元素超出父容器,父容器设置 overflow: hidden 即可:

    div {
        ....
        overflow: hidden;
        
        &::before {
            ....
            left: -20px;
            top: -10px;
            right: -20px;
            bottom: -20px;
            background: linear-gradient(
                30deg,
                rgba(229, 23, 49, 1),
                rgba(229, 23, 49, .9) 48%,
                transparent 55%,
            );
            filter: url(#smoke);
        }
    }
    

    调整之后,看看效果:

    有点那感觉了,下一步,只需要让烟雾元素动起来,为了让整个效果连贯(由于 SVG 动画本身不支持类似 animation-fill-mode: alternate 这种特性),我们还是需要写一点 JavaScript 代码,控制动画的整体循环。

    大概的代码是这样:

    const filter = document.querySelector("#turbulence");
    let frames = 1;
    let rad = Math.PI / 180;
    let bfx, bfy;
    
    function freqAnimation() {
        frames += .35;
    
        bfx = 0.035;
        bfy = 0.015;
    
        bfx += 0.006 * Math.cos(frames * rad);
        bfy += 0.004 * Math.sin(frames * rad);
    
        bf = bfx.toString() + " " + bfy.toString();
        filter.setAttributeNS(null, "baseFrequency", bf);
    
        window.requestAnimationFrame(freqAnimation);
    }
    
    window.requestAnimationFrame(freqAnimation);
    
    

    这段代码做的事情,其实只有一个,就是让 SVG 的 #turbulence 滤镜的 baseFrequency 属性,在一个区间内无限循环,仅此而已。通过改变 baseFrequency,让整个烟雾不断变化。

    至此,我们就得到了一幅完整的,会动的烟雾遮罩:

    bbg2.gif

    补充下框内的图片,就能得到一开始给出的效果图效果:

    bbg3.gif

    完整的代码,你可以戳这里 -- CodePen Demos -- LPL BAN PICK MASK Effect

    实现呼吸状态的遮罩效果

    在上述基础上,再加入呼吸的效果,其实就非常简单了。

    我们只需要去改变渐变的一个位置即可,方法非常多,这里我给一个较为优雅但是兼容性可能没那么好的方法 -- CSS @property。

    简单改造上述代码:

    @property --per {
        syntax: "<percentage>";
        inherits: false;
        initial-value: 22%;
    }
    div::before {
        ...
        background: linear-gradient(
            30deg,
            #ff0020,
            rgba(229, 23, 49, .9) var(--per),
            transparent calc(var(--per) + 8%),
        );
        filter: url(#smoke);
        animation: change 2s infinite ease-out;
    }
    @keyframes change {
        50% {
            --per: 18%;
        }
    }
    

    这样,呼吸效果就实现了:

    完整的代码,你可以戳这里 -- CodePen Demos -- LPL BAN PICK MASK Effect

    最后

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

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

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

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

    image

    如果觉得文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
    打赏支持
    +

    (^_^)打个赏喝个咖啡(^_^)

    微信支付
    支付宝支付
  • 相关阅读:
    【MySQL】(八)多表查询——内连接查询、外连接查询、子查询
    ERP系统如何改善企业的业务?
    读取s3图片并保存至excel
    微服务部署:蓝绿发布、滚动发布、灰度发布、金丝雀发布
    Java面试题大汇总
    GitHub私有派生仓库(fork仓库) | 派生仓库改为私有
    铁路轨道设备概述1:铁路轨道基础设备
    c语言:于龙加
    MySQL数据库结合项目实战SQL优化总结
    上交所Binary行情接口demo
  • 原文地址:https://www.cnblogs.com/coco1s/p/15895408.html