关于前端:LPL-BanPick-选人阶段的遮罩效果是如何实现的

9次阅读

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

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

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

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

本文将探索,在 CSS 中,咱们应该如何去实现相似的成果。

实现烟雾化遮罩成果

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

假如没有含糊的边缘,及烟雾化的成果,它其实就是一个突变:

<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,让整个烟雾一直变动。

至此,咱们就失去了一幅残缺的,会动的烟雾遮罩:

补充下框内的图片,就能失去一开始给出的效果图成果:

残缺的代码,你能够戳这里 — 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

最初

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

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

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

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

正文完
 0