История рисования — Красота CSS-анимации | Техническое эссе Nuggets — Специальное предложение в двух разделах

CSS
История рисования — Красота CSS-анимации | Техническое эссе Nuggets — Специальное предложение в двух разделах

предисловие

Всем привет, это волшебник CSS - alphardex.

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

Ну, особо нечего сказать. Давайте погрузимся в область CSS-анимации!

Маленькое пасхальное яйцо: Название этой статьи — «Нэта», это один из моих любимых мультсериалов, анимация в нем очень выразительная, и я настоятельно рекомендую всем его посмотреть.

Введение в анимацию CSS

Обычно мы привыкли использовать CSS для реализации различных статических макетов страниц. Однако какой бы красиво оформленной странице не хватало анимации, она будет такой же безжизненной, как пустая оболочка без души. Так как же дать странице душу? Ответ — анимация.

В мире CSS есть два основных способа добиться анимации: переход и анимация.В этой статье мы сосредоточимся на последнем, то есть на анимации.

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

Во-первых, давайте посмотрим на одну из следующих анимаций

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

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

Как научиться анимации

В двух словах: превратите движение в неподвижность.

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

Может использоваться многими внешними интерфейсамиТенсент Житуэто программное обеспечение? Довольно круто использовать его для пакетного сжатия изображений, но встроенныйImageMagickЗато есть малоизвестная практическая функция — пакетное преобразование gif-кадров в png. Его легко использовать в командной строке:

convert -coalesce target.gif target_%d.png

Давайте потренируемся, сохраните анимированный gif из предыдущего раздела на локальный диск, запустите указанную выше команду, вы получите все статические кадры анимации.

Немного слишком, не так ли? Не паникуйте, сначала извлеките ключевые кадры. Что такое ключевые кадры? Это кадр из двух состояний, когда анимация переключается из состояния A в состояние B, опуская все переходные кадры в середине. Ниже приведены 3 ключевых кадра анимации.

Через эти 3 ключевых кадра мы можем выполнить очень важную задачу — верстку.

Даже анимация неотделима от верстки, по всем элементам на экране можно написать следующую структуру HTML

<div class="relative flex items-center justify-center">
  <div class="bar-1">
    <div class="arrow left"></div>
    <div class="flex flex-col items-center self-stretch">
      <div class="lines top">
        <div class="line"></div>
        <div class="line"></div>
      </div>
      <div class="block">
        <span class="staggered-scale-in">High stakes table</span>
      </div>
      <div class="lines bottom">
        <div class="line"></div>
        <div class="line"></div>
      </div>
    </div>
    <div class="arrow right"></div>
  </div>
  <div class="bar-2">
    <div class="clips">
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
      <div class="clip"></div>
    </div>
    <div class="arrows">
      <div class="arrow top"></div>
      <div class="arrow right"></div>
      <div class="arrow bottom"></div>
      <div class="arrow left"></div>
    </div>
    <div class="block">
      <span class="staggered-scale-in">$100-$200</span>
    </div>
    <div class="lines">
      <div class="line left-top"></div>
      <div class="line right-top"></div>
      <div class="line left-bottom"></div>
      <div class="line right-bottom"></div>
    </div>
  </div>
</div>

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

  1. Такие фигуры, как стрелки, треугольники, параллелограммы и т. д., можно рисовать с помощью clip-path, используйте его онлайн.Веб-сайт инструментовпросто хорошо
  2. Макет должен быть реализован с использованием flex, насколько это возможно, потому что это король современной верстки CSS.
  3. Самое главное в CSS — это тонкая настройка, хорошо используйте панель CSS в devtools, она вам поможет

Когда вы успешно завершили макет, пришло время подумать о том, как его оживить.

Прежде всего, объединив 3 вышеуказанных ключевых кадра с исходной анимацией, мы можем узнать, что анимацию можно разделить на 3 части:

Часть 1: 2 стрелыarrowПоявляется слева и справа и пересекает в соответствующих направлениях; красная полоса посерединеblockрастянуты; линии над и под красной полосойlineрастянуться; текстspanв шахматном порядке; целыйbar-1Вращение исчезает

Часть II: Другое целоеbar-2Повернуть внутрь; параллелограмм расположен в шахматном порядке сверху и снизуclipДвигайтесь по диагонали к середине в шахматном порядке; 4 стрелкиarrowПоявляется сверху, снизу, слева и справа и пересекает в соответствующих направлениях

Часть 3: серая полоса посерединеblockрастянуться; текстspanв шахматном порядке; четыре строкиlineрастянуться в то же время

Далее, давайте проанализируем это предложение за предложением

(Примечание: поскольку эта статья не является учебником по анимации с нуля, поэтомуПодробное использование анимацииВ этой статье это не упоминается, пожалуйста, сделайте домашнее задание, прежде чем читать следующую часть)

Готов к работе

Я написал CSS-фреймворк, которым пользовался раньше:aqua.css, в который встроено множество полезных классов инструментов (в том числе множество функций замедления анимации), которые представлены в нашем html-коде.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@alphardex/aqua.css@1.5.5/dist/aqua.min.css" />

первая часть

part-1.gif

2 стрелкиarrowПоявляясь слева и справа и проводя пальцем в соответствующих направлениях, ключевые кадры и анимации, соответствующие этому предложению, следующие:

.arrow {
  &.left {
    animation: slide-left-in 1s var(--ease-out-quart) both;
  }

  &.right {
    animation: slide-right-in 1s var(--ease-out-quart) both;
  }
}

@keyframes slide-left-in {
  from {
    transform: translateX(1000%);
    opacity: 0;
  }

  to {
    transform: translateX(0);
  }
}

@keyframes slide-right-in {
  from {
    transform: translateX(-1000%);
    opacity: 0;
  }

  to {
    transform: translateX(0);
  }
}

средняя красная полосаblockпротянуть

.block {
  animation: scale-x-in 1.2s 0.15s var(--ease-out-quart) both;
}

@keyframes scale-x-in {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

Линии выше и ниже красной полосыlineпротянуть

.line {
  animation: scale-x-in 0.8s var(--ease-out-quart) both;
}

СловоspanВнешний вид в шахматном порядке (обратите внимание, что вы должны сначала использовать JS, чтобы разделить текст и применить анимацию в шахматном порядке, используяSplitTextплагин, у него также есть бесплатная альтернативаSplitting)

.scale-in-bounce {
  opacity: 0;
  animation: scale-in-bounce 0.2s both;
  animation-delay: calc(var(--basic-delay) + 0.05s * var(--i));
}

@keyframes scale-in-bounce {
  0% {
    opacity: 0;
    transform: scale(2.5);
  }

  40% {
    opacity: 1;
    transform: scale(0.8);
  }

  100% {
    opacity: 1;
    transform: scale(1);
  }
}
const split = new SplitText(".staggered-scale-in", {
  type: "chars",
  charsClass: "scale-in-bounce",
});
split.chars.forEach((item, i) => {
  item.style.setProperty("--basic-delay", "0.7s");
  item.style.setProperty("--i", `${i}`);
});

в общем и целомbar-1Вращение исчезает

.bar-1 {
  animation: rotate-right-out 0.3s var(--bar-1-duration) both;
}

@keyframes rotate-right-out {
  to {
    transform: rotate(90deg);
    opacity: 0;
  }
}

Вторая часть

part-2.gif

другое целоеbar-2Повернуть в

.bar-2 {
  animation: rotate-left-in 0.3s var(--bar-1-duration) both;
}

@keyframes rotate-left-in {
  from {
    transform: rotate(-45deg);
    opacity: 0;
  }
}

Параллелограмм со смещенными верхом и низомclipДвигайтесь по диагонали к середине в шахматном порядке (здесь используется псевдокласс nth-child для выбора нечетных и четных элементов)

.clip {
  &:nth-child(odd) {
    animation: slide-right-top-in 0.8s var(--ease-out-quart) both;
  }

  &:nth-child(even) {
    animation: slide-left-bottom-in 0.8s var(--ease-out-quart) both;
  }
}

@keyframes slide-right-top-in {
  from {
    transform: translate(50%, -100%);
    opacity: 0.5;
  }

  to {
    transform: translate(0, 0);
    opacity: 1;
  }
}

@keyframes slide-left-bottom-in {
  from {
    transform: translate(-50%, 100%);
    opacity: 0.5;
  }

  to {
    transform: translate(0, 0);
    opacity: 1;
  }
}

4 стрелкиarrowПоявляется сверху, снизу, слева и справа и пересекает в соответствующих направлениях

.arrow {
  &.top {
    animation: slide-bottom-in 0.8s var(--bar-2-delay) var(--ease-out-quart) both;
  }

  &.right {
    animation: slide-left-in-2 0.8s var(--bar-2-delay) var(--ease-out-quart) both;
  }

  &.bottom {
    animation: slide-top-in 0.8s var(--bar-2-delay) var(--ease-out-quart) both;
  }

  &.left {
    animation: slide-right-in-2 0.8s var(--bar-2-delay) var(--ease-out-quart) both;
  }
}

@keyframes slide-bottom-in {
  from {
    transform: translateY(300%);
    opacity: 0.5;
  }

  to {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes slide-top-in {
  from {
    transform: translateY(-300%);
    opacity: 0.5;
  }

  to {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes slide-left-in-2 {
  from {
    transform: translateX(-1150%);
    opacity: 0.5;
  }

  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slide-right-in-2 {
  from {
    transform: translateX(1150%);
    opacity: 0.5;
  }

  to {
    transform: translateX(0);
    opacity: 1;
  }
}

третья часть

part-3.gif

средняя серая полосаblockРастянуться (почти такая же красная полоса, как и раньше)

.bar {
  animation: scale-x-in 1.2s calc(var(--bar-2-delay) + 0.6s) var(--ease-out-quart) both;
}

Текст выглядит чересстрочным, как показано выше.

Наконец, четыре строкиlineПотянитесь одновременно (обратите внимание, что они ориентированы по-разному, поэтому измените их центр движения).

.line {
  &.left-top {
    transform-origin: right;
    animation: scale-x-in 0.8s calc(var(--bar-2-delay) + 0.8s) var(--ease-out-quart) both;
  }

  &.right-top {
    transform-origin: left;
    animation: scale-x-in 0.8s calc(var(--bar-2-delay) + 0.8s) var(--ease-out-quart) both;
  }

  &.left-bottom {
    transform-origin: right;
    animation: scale-x-in 0.8s calc(var(--bar-2-delay) + 0.8s) var(--ease-out-quart) both;
  }

  &.right-bottom {
    transform-origin: left;
    animation: scale-x-in 0.8s calc(var(--bar-2-delay) + 0.8s) var(--ease-out-quart) both;
  }
}

Конечный продукт:Здесь Мэнчуо

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

CSS-приемы анимации

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

ошеломленный

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

<div class="blocks">
  <div class="block block-1"></div>
  <div class="block block-2"></div>
  <div class="block block-3"></div>
  <div class="block block-4"></div>
</div>
.block {
  animation: scale-in-center 0.8s var(--ease-out-cubic) both;

  &-1 {
    animation-delay: 0;
  }

  &-2 {
    animation-delay: 0.3s;
  }

  &-3 {
    animation-delay: 0.45s;
  }

  &-4 {
    animation-delay: 0.6s;
  }
}

@keyframes scale-in-center {
  from {
    transform: scale(0);
  }

  to {
    transform: scale(1);
  }
}

Этот демонстрационный адрес:Motion Table - Symmetric Scale

Инсульт

Шестиугольники можно рисовать с помощью программного обеспечения для векторного рисования (автор использовалInkScape)

Эффект обводки управляет этими двумя свойствами:stroke-dasharrayа такжеstroke-offset, первый контролирует длину пунктирной линии svg, а второй управляет смещением пунктирной линии svg, Когда первый достаточно велик, управление значением последнего может достичь эффекта штриха

<div class="hexagon" style="--i: 1">
  <svg width="6rem" viewBox="0 0 68.982 79.653" xmlns="http://www.w3.org/2000/svg" class="half left">
    <path d="M34.492 78.5L1.001 59.164V20.492L34.492 1.156l33.491 19.336v38.672z" fill="none" stroke-width="2" />
  </svg>
  <svg width="6rem" viewBox="0 0 68.982 79.653" xmlns="http://www.w3.org/2000/svg" class="half right">
    <path d="M34.492 78.5L1.001 59.164V20.492L34.492 1.156l33.491 19.336v38.672z" fill="none" stroke-width="2" />
  </svg>
</div>
.hexagon {
  .half {
    stroke-dasharray: 233;
    animation: stroke-in 1s both;

    &.right {
      transform: scaleX(-1);
    }
  }
}

@keyframes stroke-in {
  from {
    stroke-dashoffset: 236;
  }

  to {
    stroke-dashoffset: 117;
  }
}

Этот демонстрационный адрес:Motion Table - Repeat Scale

круговое движение

Прежде всего, родительский элемент, несомненно, вращается вокруг центра на 360. Ключевым моментом является то, что расстояние смещения дочернего элемента должно быть равно радиусу кольца, чтобы можно было добиться эффекта кругового вращения.

<div class="orbit">
  <div class="point"></div>
</div>
.orbit {
  .point {
    animation: spin var(--spin-duration) var(--spin-delay) linear infinite;

    &::before {
      transform: translateX(calc((var(--orbit-width)) / 2));
    }
  }
}

@keyframes spin {
  from {
    transform: rotate(0);
  }

  to {
    transform: rotate(1turn);
  }
}

Этот демонстрационный адрес:Motion Table - Orbit

3d перспектива

Настройки родительского элементаtransform-style: preserve-3dа такжеperspective, дочерние элементы могут быть преобразованы в 3D

<div class="camera">
  <div class="cards">
    <div class="card"></div>
    ...
  </div>
</div>
.camera {
  transform-style: preserve-3d;
  perspective: 200px;
  transform: rotateX(60deg) rotateZ(35deg) scale(1.1);
}

Этот демонстрационный адрес:Motion Table - Depth Of Field

На самом деле, складное уведомление IOS также типично для преобразования 3D, следующие CSS - это его анимированная версия реализации

Видите пасхальные яйца? Правильно, это весна

Этот демонстрационный адрес:IOS Notification Fold Toggle

случайность

Следующие два миксина SCSS в основном используются для генерации случайных данных.

@function random_range($min, $max) {
  $rand: random();
  $random_range: $min + floor($rand * (($max - $min) + 1));
  @return $random_range;
}

@function sample($list) {
  @return nth($list, random(length($list)));
}

Этот демонстрационный адрес:Bubble Ring

усечение

в основном используетсяoverflow: hiddenЭто свойство отсекает лишнее и может использоваться для имитации различных эффектов (например, штрихов).

Этот демонстрационный адрес:Frame Text Reveal

наконец

все еще яйцо

Вдохновение для этой анимации:Начните с Monogatari Эпизод 3

Этот демонстрационный адрес:3D Puzzle Animation

🏆 Техническое эссе Nuggets | Специальная двойная секция