Recently S11 LPL spring season started. While watching the game, I noticed a new and interesting mask effect appeared in the Ban/Pick phase of the new season, as shown in the picture below:

Of course, it is a dynamic effect, the process of being elected, there will be a kind of breathing effect:

The Gif is a bit of a blur and, in general, a mask effect that is close to fog. And it can change dynamically.

This article explores how we can achieve a similar effect in CSS.

Achieve smoke mask effect

First, let’s try to implement such a dynamic mask:

Assuming there are no blurry edges and a smoky effect, it’s actually a gradient:

<div></div>
Copy the code
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%,); }Copy the code

From the above code, we can get:

Okay, that looks pretty plain, but how do we take advantage of that and get a fogging effect?

When it comes to smog, those of you who are smart can think of a filter, of course, the < Feturbulence > filter for SVG.

Yes, it is again, < FeTurbulence > is really interesting, my last two articles about it – Amazing!! Can CSS also achieve smoke effect? , backpacks!!!!! Can CSS also implement aurora? You can read it together.

< FeTurbulence > type=”fractalNoise” is useful for simulating cloud effects. The filter uses the Perlin noise function to create an image that is able to achieve a semi-transparent smoky or wavy image for some special textures.

Here, we use the < FeTurbulence > filter to deal with the above figure briefly:

<div></div>

<svg width="0">
  <filter id="filter">
    <feTurbulence id="turbulence" type="fractalNoise" baseFrequency="3" numOctaves="20" />
    <feDisplacementMap in="SourceGraphic" scale="30" />
  </filter>
</svg>
Copy the code

In CSS, you can use filter: url() to apply this filter to the corresponding element:

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

The effect of the element with the filter:

Since I added a border to the element, the entire border is also atomized, which is not what we want, we can change it by using pseudo-elements. Borders apply to the container, using pseudo-elements for gradient, and applying filters to pseudo-elements:

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); }}Copy the code

The effect after transformation is as follows:

Okay, one step closer, but there’s a lot of imperfections around that haven’t been filled in. 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); }}Copy the code

After adjustment, see the effect:

The next step is to animate the smoke element, in order to make the effect coherent (since SVG animations themselves don’t support animation-fill-mode) : Alternate this feature), we still need to write a little JavaScript code to control the overall animation loop.

The code looks like this:

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. Bfy += 0.004 * Math. Sin (frames * rad); bf = bfx.toString() + " " + bfy.toString(); filter.setAttributeNS(null, "baseFrequency", bf); window.requestAnimationFrame(freqAnimation); } window.requestAnimationFrame(freqAnimation);Copy the code

The only thing this code does is make the baseFrequency property of SVG’s # Turbulence filter loop in an interval indefinitely. By changing the baseFrequency, the overall smoke is constantly changing.

At this point, we have a complete, moving smoke mask:

Add the image in the box to get the effect shown at the beginning:

For the full code, you can poke here — CodePen Demos — LPL BAN PICK MASK Effect

Realize the mask effect of breathing state

On the above basis, and then add the effect of breathing, in fact, it is very simple.

We only need to change one part of the gradient. There are a lot of ways to do this, but I’m going to give you a more elegant but perhaps less compatible method called CSs@property.

Simply modify the above code:

@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%; }}Copy the code

In this way, the breathing effect is achieved:

For the full code, you can poke here — CodePen Demos — LPL BAN PICK MASK Effect

The last

Well, that’s the end of this article, I hope you found it helpful 🙂

Want to Get the most interesting CSS information, do not miss my public account – iCSS front-end interesting news 😄

More interesting CSS technology articles are summarized in my Github — iCSS, constantly updated, welcome to click on the star subscription favorites.

If there are any questions or suggestions, you can exchange more original articles, writing is limited, talent and learning is shallow, if there is something wrong in the article, hope to inform.