Как создать зигзагообразные CSS-загрузчики, используя один элемент

В предыдущей статье я показал вам, как создать коллекцию загрузчиков filling CSS, в которой каждый загрузчик был создан с использованием одного HTML-элемента. Здесь вы узнаете больше о загрузчиках, создав коллекцию Zig-Zag.

Вот краткий обзор того, что вы будете создавать:

Вы также можете ознакомиться с моей онлайн-коллекцией, чтобы увидеть до 20 вариантов использования зигзагообразной формы.

Мы не будем изучать все варианты, но я покажу вам несколько приемов, которые помогут вам создать столько вариантов, сколько вы захотите.

Как создать зигзагообразную форму

Первым шагом является создание зигзагообразной фигуры. Для этого вы можете взять код с моего веб-сайта CSS shape: https://css-shape.com/zig-zag-line/.

Вы можете настроить различные переменные, чтобы получить желаемый зигзаг. В нашем случае я буду использовать более простую версию без переменных.

.loader {
  height: 47px; /* control the size */
  aspect-ratio: 5;
  background:
   conic-gradient(from 135deg at top,#000 90deg,#0000 0) top,
   conic-gradient(from 135deg at top,#0000 90deg,#000 0) bottom;
  background-size: 20% 50%;
  background-repeat: repeat-x;
}

А вот рисунок, иллюстрирующий, как эти градиенты создают форму:

Первый градиент создал красную часть, а второй - зеленую. У нас есть две треугольные формы, которые повторяются по горизонтали.

Поскольку мы хотим, чтобы было пять повторений, я использовал соотношение сторон: 5 и 20% (100%/5) в качестве размера фона. Вы можете сделать его более универсальным, введя переменную для управления количеством повторений, но, как я уже говорил ранее, я собираюсь упростить процедуру.

Я хочу отметить, что при использовании градиентов вы можете добиться того же результата, используя другой синтаксис. Например, я могу обновить предыдущий код следующим образом:

.loader {
  height: 47px; /* control the size */
  aspect-ratio: 5;
  background:
   conic-gradient(from 135deg at top   ,#000 90deg,#0000 0),
   conic-gradient(from -45deg at bottom,#000 90deg,#0000 0) 12.5% 100%;
  background-size: 20% 50%;
  background-repeat: repeat-x;
}

Это все тот же результат, но с другим синтаксисом для второго градиента. Вы заметили повторяющуюся часть в градиентах? Эта часть управляет цветом, и мы можем определить ее как переменную, чтобы избежать повторения и иметь возможность обновлять цвет только один раз в коде.

.loader {
  height: 47px; /* control the size */
  aspect-ratio: 5;
  --c:#000 /* the color */ 90deg,#0000 0;
  background:
   conic-gradient(from 135deg at top   ,var(--c)),
   conic-gradient(from -45deg at bottom,var(--c)) 12.5% 100%;
  background-size: 20% 50%;
  background-repeat: repeat-x;
}

Теперь у нас есть наша зигзагообразная форма, и мы готовы ее анимировать.

Как анимировать зигзагообразную форму

Поскольку мы используем фон, мы анимируем положение фона, чтобы получить наш первый загрузчик. Идея заключается в перемещении градиентов по горизонтали и создании бесконечного движения.

.loader {
  height: 47px; /* control the size */
  aspect-ratio: 5;
  --c:#000 /* the color */ 90deg,#0000 0;
  background:
   conic-gradient(from 135deg at top   ,var(--c)),
   conic-gradient(from -45deg at bottom,var(--c)) 12.5% 100%;
  background-size: 20% 50%;
  background-repeat: repeat-x;
  animation: loading .8s infinite linear;
}

@keyframes loading {
  0%   {background-position: 0   0,12.5% 100%}
  100% {background-position: 25% 0,37.5% 100%}
}

Обратите внимание, что мы увеличили значение X для позиции фона на 25%. Если вам интересно, какая логика стоит за этим значением, вот формула:

0.2 / (1 - 0.2) = .25 = 25%

.2 соответствует 20%, используемым внутри размера фона.

У нас есть наш первый загрузчик! На самом деле, два загрузчика, потому что мы можем легко изменить направление движения, добавив анимацию-направление: обратное.

Давайте попробуем другую анимацию: используя clip-path и значение inset(). Мы можем легко настроить этот метод для создания множества вариаций.

Давайте начнем с простого примера:

.loader {
  /* same code as previously */
  animation: loading .8s infinite linear;
}
@keyframes loading {
  0%   {clip-path: inset(0 100% 0 0)}
  100% {clip-path: inset(0 0    0 0)}
}

Значение inset() создает прямоугольник, в котором будет видна только часть внутри него. Для этого мы определили расстояние от каждой стороны элемента (сверху, справа, снизу, слева).

Логически, вставка(0 0 0 0) показывает весь элемент целиком, поскольку все расстояния равны 0, но вставка(0 100% 0 0) полностью скрывает элемент, поскольку правильное значение равно 100%. Таким образом, он коснется противоположного края, создавая пустой прямоугольник.

Изменяя это правильное значение от 100% до 0, мы создаем анимацию раскрытия. Еще один вариант загрузки!

Если вы посмотрите на код второй анимации, то увидите, что я сделал то же самое, но с левой стороны.

Мы также можем добиться эффекта скольжения, если анимируем как левое, так и правое значения, сохраняя при этом их разницу постоянной.

.loader {
  /* same code as previously */
  animation: loading .8s infinite linear;
}
@keyframes loading {
  0%   {clip-path: inset(0 60% 0 0  )}
  100% {clip-path: inset(0 0   0 60%)}
}

Правое значение изменяется от 60% до 0, а левое - от 0 до 60%, таким образом, мы получаем постоянную разницу в 60%, которая создаст иллюзию скользящего прямоугольника. Еще один классный загрузчик!

Пробуя различные комбинации значений inset, вы можете получить множество загрузчиков CSS. Попробуйте! Вы также можете просмотреть мою онлайн-коллекцию и попытаться определить варианты, в которых используется clip-path: inset().

Как создать дискретную анимацию

Чтобы добиться дискретной анимации, вы можете использовать функцию синхронизации steps() вместо линейной. Давайте начнем с первого примера, используя шаги(2).

Мы можем сделать то же самое практически со всеми вариантами. Давайте попробуем с теми, в которых используется clip-path: inset().

.loader {
  /* same code as previously */
  animation: loading .8s infinite steps(5);
}
@keyframes loading {
  0%   {clip-path: inset(0 100% 0 0)}
  100% {clip-path: inset(0 0    0 0)}
}

У нас есть пять повторений, так что давайте посмотрим, чего мы добьемся с помощью шагов(5).

На данный момент это не очень хорошо, потому что мы не видим всех повторений. Анимация останавливается на 4 повторениях. На самом деле нам нужно 6 шагов, а не 5.

.loader {
  /* same code as previously */
  animation: loading .8s infinite steps(6);
}
@keyframes loading {
  0%   {clip-path: inset(0 100% 0 0)}
  100% {clip-path: inset(0 0    0 0)}
}

Даже при выполнении 6 шагов результат все равно остается неудовлетворительным, но не волнуйтесь, это не ошибка. Поведение steps() по умолчанию выдает ожидаемый результат, поэтому мы должны обновить его следующим образом:

.loader {
  /* same code as previously */
  animation: loading .8s infinite steps(6,jump-none);
}
@keyframes loading {
  0%   {clip-path: inset(0 100% 0 0)}
  100% {clip-path: inset(0 0    0 0)}
}

Если вы не знакомы с параметром jump-none, это значение может устранить большинство проблем при работе с steps(). Я написал короткую статью об этом, если вы хотите узнать больше подробностей: "Как правильно использовать steps() с анимацией".

Теперь наша анимация выглядит идеально! Мы также можем сделать ее 11-шаговой (5-2 + 1) и получить еще один классный загрузчик.

Даже эффект скольжения может иметь свои дискретные вариации.

Можете ли вы понять, почему я использую 4 и 7 шаги? Я позволю вам выполнить расчет в виде небольшого упражнения.

Вывод

В этой статье показано, как создавать фигуры, как анимировать их с помощью контура клипа и как создавать дискретную анимацию. Вы также можете рассмотреть дополнительные приемы, например, использовать оба псевдоэлемента для создания двух фигур.

Я не рассматривала все варианты, но теперь у вас есть рецепт, по которому вы сможете приготовить еще больше!

Вы можете ознакомиться с моей коллекцией зигзагообразных погрузчиков, изучить другие варианты и попробовать создать свой собственный погрузчик. Это хорошая возможность применить на практике то, что вы узнали из этой статьи.