Ранее я представил несколько способов достижения волнового эффекта с помощью чистого CSS, о них есть две связанные статьи:
- Чистый CSS для достижения эффекта волны!
- Разумное использование CSS для получения крутой анимации зарядки
В этой статье будет представлен еще один волновой эффект с использованием CSS, идея очень интересная.
Из определенного интеграла реализовать площадь изогнутого треугольника
Прежде чем перейти к теме, сначала посмотрите на это, в высшей математике мы можем найти площадь графика квадратичной функции с кривыми ребрами путем определенного интегрирования.
Мы можем разделить площадь под кривой на n тонких прямоугольников, Когда n стремится к бесконечности, площадь всех прямоугольников равна площади изогнутой фигуры.
Две простые схемы взяты изПочему определенный интеграл может найти площадь?:
При приближении n к бесконечности площадь всех прямоугольников равна площади фигуры с изогнутыми краями:
Используя эту идею, мы также можем смоделировать изогнутый край, который представляет собой волнистую линию, в CSS с помощью нескольких элементов div.
Шаг 1. Разрежьте рисунок на несколько копий
Во-первых, мы можем определить родительский контейнер с 12 дочерними элементами под ним:
<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>
пройти черезflex
Разметка, просто раскладка, получается такая графика, каждый дочерний элемент имеет одинаковую высоту:
.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;
}
Эффект следующий:
Шаг 2. Пусть каждый ребенок запустит анимацию преобразования высоты с разными отрицательными задержками.
Далее с помощью простого преобразования нам нужно заставить этот график двигаться, изменяя высоту каждого дочернего элемента:
.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;
}
}
Эффект следующий:
Далее нужно только задать отрицательную задержку разного времени для анимационной последовательности каждого подэлемента, и можно получить предварительный эффект волны.Здесь для снижения нагрузки используем SASS для достижения:
$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;
}
}
Таким образом, мы получаем предварительный волновой эффект:
Шаг 3. Сглаживание
Видно, что в приведенной выше волновой анимации есть определенная неровность, и следующее, что нам нужно сделать, это максимально устранить эти неровности.
Способ 1: увеличить количество div
В соответствии с идеей использования определенного интеграла для нахождения площади графики с кривыми краями в начале нам нужно только максимально увеличить количество дочерних элементов div.Когда количество элементов div бесконечно, пилообразный исчезнет.
Мы можем попробовать заменить указанные выше 12 подразделов на 120. Слишком трудоемко писать 120 разделов один за другим.PugДвижок шаблона:
div.g-container
-for(var i=0; i<120; i++)
div.g-item
Для кода CSS вам нужно только изменить время задержки анимации, а отрицательная задержка 120 дочерних элементов div контролируется в течение 1 с:
// 12 -- 120
$count: 120;
$speed: 1s;
.g-item {
// 注意,只有这里发生了变化
--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});
}
}
Таким образом, мы можем получить относительно гладкую кривую:
Метод 2: имитация радианов через преобразование: skew()
Конечно, в действительности использование такого количества элементов div слишком расточительно, поэтому есть ли какой-либо другой способ максимально устранить алиасинг, когда количество элементов div относительно невелико?
Здесь мы можем попробовать добавить разныеtransform: skewY()
для имитации радианов.
Давайте еще раз изменим код, уменьшим количество div и добавим еще по одному на каждый дочерний divtransform: skewY()
Эффект анимации:
div.g-container
-for(var i=0; i<24; i++)
div.g-item
Полный код CSS выглядит следующим образом:
$count: 24;
$speed: 1s;
.g-item {
// 注意,只有这里发生了变化
--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);
}
}
Чтобы облегчить понимание, давайте сначала посмотрим, что когда анимация преобразования высоты непротиворечива, добавляется дочерний элемент div.skewY()
Как выглядит трансформация:
Можно видеть, что каждое преобразование имеет очевидную выступающую пилообразную форму, и наложение задержанного преобразования высоты может хорошо устранить большую часть пилообразного эффекта:
На данный момент у нас есть еще один метод сглаживания с умеренным количеством div! Полный код для всех вышеперечисленных эффектов вы можете нажать здесь:
CodePen -- PureCSS Wave Effects
Смешанное использование
Наконец, мы можем комбинировать несколько различных волновых эффектов, регулируя несколько переменных параметров, чтобы получить несколько комбинированных эффектов, что тоже очень хорошо.
Что-то вроде этого:
CodePen -- PureCSS Wave Effects 2
Исходя из этого, я думаю о ЛОГОТИПЕ головной компании нашей компании (Shopee) — Sea Group, который выглядит следующим образом:
Используя схему из этой статьи, придайте ему динамическую анимацию ЛОГОТИПА:
CodePen Demo -- PureCSS Wave - Sea Group Logo
недостаток
Недостатки этой схемы все же очевидны:
- Первый — это ненужный div, который требует большего количества div для достижения эффекта, и чем больше divов, тем лучше эффект.Конечно, если он увеличится до определенной степени, заморозка неизбежна.
- Пилообразный нельзя полностью устранить, это самое смертоносное или то место, где его действительно можно использовать.
Конечно, цель этой статьи состоит в том, чтобы развить больше мышления, обсудить преимущества и недостатки этого метода, понять весь процесс анимации и использовать отрицательное время задержки анимации, все из которых имеют некоторое справочное значение для обучения. CSS по-прежнему очень интересен~ 🤣
наконец
Ну вот и конец этой статьи, надеюсь она вам поможет :)
Если вы хотите получить самую интересную информацию о CSS, не пропустите мой официальный аккаунт --Интересные факты о внешнем интерфейсе iCSS😄
Другие замечательные технические статьи по CSS собраны в моемGithub -- iCSS, продолжайте обновлять, добро пожаловать, нажмите звездочку, чтобы подписаться на коллекцию.
Если у вас есть какие-либо вопросы или предложения, вы можете общаться больше.Оригинальные статьи ограничены в написании и знаниях.Если в статье есть какие-либо неточности, пожалуйста, дайте мне знать.