Ideas for creating wave effects with CSS

Ideas for creating wave effects with CSS

Previously, I introduced several ways to achieve wave effects using pure CSS. There are two related articles about them:

Pure CSS to achieve wave effect!

Use CSS to achieve cool charging animation

This article will introduce another wave effect achieved using CSS, the idea is very interesting.

Let's start with realizing the area of ​​a curved triangle from definite integral

Before we get into the topic, let's take a look at this. In advanced mathematics, we can use definite integrals to find the area of ​​the curved side figure of a quadratic function.

We can divide the area under the curve into n thin and tall rectangles. When n approaches infinity, the area of ​​all rectangles is equal to the area of ​​the curved figure.

Two simple diagrams, taken from Why can definite integrals be used to calculate area? :

As n approaches infinity, the area of ​​all rectangles equals the area of ​​the curved figure:

Using this idea, we can also simulate a curved edge, that is, a wavy line, in CSS through multiple divs.

Step 1. Cut the image into multiple pieces

First, we can define a parent container with 12 child divs under it:

<div class="g-container">
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
  <div class="g-item"></div>
</div>

Through flex layout, a simple layout is obtained, and each child element has the same height:

.g-container {
    width: 200px;
    height: 200px;
    border: 2px solid #fff;
    display: flex;
    align-items: flex-end;
}

.g-item {
    flex-grow: 1;
    height: 60px;
    background-color: #fff;
}

The effect is as follows:

Step 2. Let each child element run the height transformation animation with different negative delays

Next, with a simple modification, we need to make this graph animated, which can be achieved by changing the height of each child element:

.g-item {
    flex-grow: 1;
    height: 60px;
    background-color: #000;
    animation: heightChange 1s infinite ease-in-out alternate;
}

@keyframes heightChange {
    from {
        height: 60px;
    }
    to {
        height: 90px;
    }
}

The effect is as follows:

Next, we only need to set a negative delay of different time for each child element's animation sequence to get a preliminary wave effect. To reduce the workload, we use SASS to achieve this:

$count: 12;
$speed: 1s;

.g-item {
    --f: #{$speed / -12};
    flex-grow: 1;
    height: 60px;
    background-color: #000;
    animation: heightChange $speed infinite ease-in-out alternate;
}

@for $i from 0 to $count {
    .g-item:nth-child(#{$i + 1}) {
        animation-delay: calc(var(--f) * #{$i});
    }
}

@keyframes heightChange {
    from {
        height: 60px;
    }
    to {
        height: 90px;
    }
}

In this way, we get a preliminary wave effect:

Step 3. Eliminate aliasing

As you can see, the above wave animation has some jagged edges. What we need to do next is to eliminate these jagged edges as much as possible.

Method 1: Increase the number of divs

According to the idea of ​​using definite integral to find the area of ​​the curved edge figure at the beginning, we only need to increase the number of sub-divs as much as possible. When the number of divs is infinite, the jagged edges will disappear.

We can try to replace the above 12 child divs with 120. It is too laborious to write 120 divs one by one. Here we use the Pug template engine:

div.g-container
 -for(var i=0; i<120; i++)
    div.g-item

For the CSS code, you only need to change the animation delay time. The negative delay of 120 child divs is controlled within 1s:

// 12 -- 120
$count: 120;
$speed: 1s;

.g-item {
    // Note that only this has changed -- f: #{$speed / -120};
    flex-grow: 1;
    height: 60px;
    background-color: #000;
    animation: heightChange $speed infinite ease-in-out alternate;
}

@for $i from 0 to $count {
    .g-item:nth-child(#{$i + 1}) {
        animation-delay: calc(var(--f) * #{$i});
    }
}

In this way, we can get a smoother curve:

Method 2: Simulate radians with transform: skew()

Of course, in reality, using so many divs is a waste. So is there any other way to eliminate aliasing as much as possible when the number of divs is relatively small?

Here, we can try to add different transform: skewY() to the child elements during the motion transformation to simulate the arc.

Let's modify the code again. We will reduce the number of divs and add a transform: skewY() animation effect to each child div:

div.g-container
 -for(var i=0; i<24; i++)
    div.g-item

The complete CSS code is as follows:

$count: 24;
$speed: 1s;

.g-item {
    // Note that only this has changed -- f: #{$speed / -24};
    flex-grow: 1;
    height: 60px;
    background-color: #000;
    animation: 
        heightChange $speed infinite ease-in-out alternate,
        skewChange $speed infinite ease-in-out alternate;
}

@for $i from 0 to $count {
    .g-item:nth-child(#{$i + 1}) {
        animation-delay: 
            calc(var(--f) * #{$i}), 
            calc(var(--f) * #{$i} - #{$speed / 2});
    }
}

@keyframes heightChange {
    from {
        height: var(--h);
    }
    to {
        height: calc(var(--h) + 30px);
    }
}

@keyframes skewChange {
    from {
        transform: skewY(20deg);
    }
    to {
        transform: skewY(-20deg);
    }
}

To make it easier to understand, first take a look at how the child div is transformed with skewY() added when the height transformation animation is consistent:

You can see that each transformation has obvious jagged edges. By adding the delayed height transformation, most of the jagged edges can be eliminated:

At this point, we have obtained another method to eliminate aliasing with a moderate number of divs! You can find the complete code for all the above effects here:

CodePen – PureCSS Wave Effects

Mixed Use

Finally, we can combine several different wave effects together by adjusting several variable parameters to get some combined effects, which is also very good.

Something like this:

CodePen – PureCSS Wave Effects 2

Based on this, I think of the logo of our company (Shopee)’s parent company, Sea Group, which looks like this:

Using the solution in this article, we can implement a dynamic LOGO animation for it:

CodePen Demo -- PureCSS Wave - Sea Group Logo

shortcoming

The disadvantages of this solution are still obvious:

First of all, it is useless div. More divs are needed to achieve the effect, and the more divs there are, the better the effect will be. Of course, when it increases to a certain extent, lag is inevitable and jagged edges cannot be completely eliminated. This is the most fatal or the place where it can really be useful.

Of course, the purpose of this article is to broaden your thinking, explore the pros and cons of this method, realize the entire process of animation, and use the negative delay time of animation, which are all of some reference and learning significance. CSS is still very interesting~ 🤣

at last

Well, this article ends here, I hope it helps you😃

This is the end of this article about the ideas of using CSS to create wave effects. For more relevant content about using CSS to create waves, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope that everyone will support 123WORDPRESS.COM in the future!

<<:  Detailed explanation of HTML element height, offsetHeight, clientHeight, scrollTop, etc.

>>:  HTML user registration page settings source code

Recommend

Detailed explanation of the order of JS object traversal

Some of you may have heard that the order of trav...

Vue2.x configures routing navigation guards to implement user login and exit

Table of contents Preface 1. Configure routing na...

mySql SQL query operation on statistical quantity

I won't say much nonsense, let's just loo...

A brief analysis of the four import methods and priorities in CSS

First: 4 ways to introduce CSS There are four way...

In-depth understanding of MySQL master-slave replication thread state transition

Preface The basic principle of MySQL master-slave...

JS realizes special effects of web page navigation bar

This article shares with you a practical web navi...

Linux MySQL root password forgotten solution

When using the MySQL database, if you have not lo...

CSS solves the misalignment problem of inline-block

No more nonsense, post code HTML part <div cla...

Apache Spark 2.0 jobs take a long time to finish when they are finished

Phenomenon When using Apache Spark 2.x, you may e...

Examples and comparison of 3 methods for deduplication of JS object arrays

Table of contents 1. Comparison of data before an...