Как улучшить CSS анимацию с помощью кубической кривой Безье
Дата публикации: 2016-05-20
От автора: в этой статье мы окунемся в замечательный мир функций кривых Безье и получим полный контроль над CSS анимацией. Давайте узнаем, как улучшить css анимацию.
Плавные переходы и анимация произвели фурор в веб-разработке, и это заслуженно. Отличный инструмент, простой, полезный, способный сделать из просто хороших front-end компонентов и интерфейсов конфетку. Способ объявления анимации и переходов похожи, для этого необходимы всего две вещи:
В случае с переходами необходимо выбрать свойство, которое будет подвержено плавному переходу. Для анимации же выбирается keyframe блок.
Потом необходимо объявить длительность задержки анимации или перехода.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
У переходов и анимации есть еще одно общее свойство, вычисляющее промежуточные значения состояний — transition timing function. Данный параметр необязателен, по умолчанию стоит ease. По умолчанию нам доступны следующие тайминг функции:
ease – анимация немного ускоряется к середине и замедляется в конце
ease-in – медленное начало и постепенное ускорение до конца
ease-out – быстрое начало и постепенное затухание к концу
ease-in-out – медленное начало, ускорение до середины и постепенное затухание к концу
linear – постоянная скорость анимации
step-start – перепрыгивает в последнее состояние анимации в первом кадре
step-end – перепрыгивает в последнее состояние в последнем кадре анимации
steps(n, start|end) – перепрыгивает через «n»’ое количество кадров анимации, тем самым «съедая» или начальный или конечный кадр
При работе с простыми переходами и анимацией вам, скорее всего, не понадобятся функции step – данные функции больше подходят для мультяшной keyframe анимации, которая крайне редко используется. Вы, возможно, использовали множество других встроенных тайминг функций для улучшения кнопок, меню, модальных окон и других компонентов с отслеживаемыми состояниями. Но вы когда-нибудь думали о том, что несмотря на эффект накопления анимации, она все равно смотрится как-то не так?
Кубическая кривая Безье идет на помощь!
Немного отойдем от темы. Люди, работавшие с анимацией, знают, что ПО типа Flash и After Effects идет с кучей функций анимации — easeInQuint, easeOutSine, easeInOutCubic – и это только 3 из большого списка. С помощью ключевых слов CSS типа ease и linear мы не можем вызвать эти функции. Однако стоит сказать, что все эти функции, включая функции с ключевыми словами в CSS, это всего лишь функции кубической кривой Безье. Но что такое эта кубическая кривая Безье? Обратим внимание на изображение ниже:
На рисунке представлен граф с максимальным значением по осям 1 или декартова система координат кубической кривой Безье. Примечание: точки в графе могут выходить за пределы 1 только по оси У (оси свойства), а вот по оси Х этого делать нельзя (оси времени). Серые линии – оси, оранжевая линия – кривая тайминг функции, голубые линии с точками – контрольные точки и линии кривой Безье. С помощью контрольных точек можно изменять форму кривой, помимо этого точки – это одна из фундаментальных концепций в ПО для векторной графики типа Adobe Illustrator.
Мы можем анимировать отдельный вид кривой Безье — кубическую кривую – с помощью четырех контрольных точек ее можно математически задать в плоскости графа, показанного выше. Однако в CSS анимации нас заботят только точки p1 и p2, так как точка p0 всегда будет 0,0, а точка p3 всегда будет 1,1. Так как же задать функцию кубической кривой Безье в CSS? Вот так:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
2.20. CSS3-переходы
CSS3-переходы могут применяться не ко всем свойствам и их значениям. Подробный перечень вы найдёте на этой странице.
Создание плавных изменений свойств элементов
Поддержка браузерами
1. Название свойства transition-property
Содержит название CSS-свойств, к которым будет применен эффект перехода. Значение свойства может содержать как одно свойство, так и список свойств через запятую. При создании перехода можно использовать как начальное, так и конечное состояние элемента. Свойство не наследуется.
Создаваемые эффекты должны быть ненавязчивыми. Не все свойства требуют плавного изменения во времени, что связано с пользовательским опытом. Например, при наведении на ссылку мы хотим видеть мгновенную смену цвета ссылки или цвета и стиля подчёркивания. Поэтому переходы следует использовать для тех свойств, к которым действительно нужно привлечь внимание.
| transition-property | |
|---|---|
| Значения: | |
| none | Отсутствие свойства для перехода. |
| all | Значение по умолчанию. Применяет эффект перехода ко всем свойствам элемента. |
| свойство | Определяет список CSS-свойств, перечисленных через запятую, участвующих в переходе. |
| initial | Устанавливает значение свойства в значение по умолчанию. |
| inherit | Наследует значение свойства от родительского элемента. |
2. Продолжительность перехода transition-duration
Задаёт промежуток времени, в течение которого должен осуществляться переход. Если разные свойства имеют разные значения для перехода, они указываются через запятую. Если продолжительность перехода не указана, то анимация при смене значений свойств происходить не будет. Свойство не наследуется.
3. Функция перехода transition-timing-function
Свойство задаёт временную функцию, которая описывает скорость перехода объекта от одного значения к другому. Если вы определяете более одного перехода для элемент, например, цвет фона элемента и его положение, вы можете использовать разные функции для каждого свойства. Свойство не наследуется.
Для создания более реалистичных анимаций используйте функцию cubic Bézier:
4. Задержка перехода transition-delay
Необязательное свойство, позволяет сделать так, чтобы изменение свойства происходило не моментально, а с некоторой задержкой. Не наследуется.
| transition-delay | |
|---|---|
| Значения: | |
| время | Время задержки перехода указывается в секундах или миллисекундах. |
| initial | Устанавливает значение свойства в значение по умолчанию. |
| inherit | Наследует значение свойства от родительского элемента. |
5. Краткая запись перехода
Все свойства, отвечающие за изменение внешнего вида элемента, можно объединить в одно свойство transition
transition: transition-property transition-duration transition-timing-function transition-delay;
Если воспользоваться значениями по умолчанию, то запись
6. Плавный переход нескольких свойств
Для элемента можно задать несколько последовательных переходов, перечислив их через запятую. Каждый переход можно оформить своей временной функцией.
7. Примеры переходов для различных свойств
Наведите курсором мыши на блоки, чтобы увидеть свойства в действии.
Расширенная анимация CSS с использованием cubic-bezier()
Дата публикации: 2021-06-09
От автора: имея дело со сложной анимацией CSS, есть тенденция создавать экспансивные @keyframes с большим количеством объявлений. Однако есть пара приемов, о которых я хочу поговорить, они могут помочь упростить задачу, оставаясь при этом ванильным CSS.
Первый более широко используется и знаком многим, а второй менее распространен. Для этого могут быть веские причины — объединять анимации с помощью запятых относительно проще, чем разбираться в различных доступных нам функциях синхронизации и том, что они делают. Есть одна особенно удобная функция синхронизации, которая дает нам полный контроль над созданием пользовательской функций времени. Это cubic-bezier() и в этом посте я покажу вам ее силу и то, как ее можно использовать для создания чудесной анимации без особой сложности.
Начнем с базового примера, показывающего, как мы можем перемещать мяч в определённых направлениях, например, в форме бесконечности (∞):
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
CodePen Embed Fallback
Как видите, здесь нет сложного кода — только два ключевых кадра и функция cubic-bezier(). И все же мы получаем довольно сложную финальную анимацию бесконечной формы. Круто, правда? Давайте вникнем в это!
Функция cubic-bezier()
Начнем с официального определения: Кубическая функция ослабления Безье — это тип функции ослабления, определяемый четырьмя действительными числами, которые определяют две контрольные точки, P1 и P2, кубической кривой Безье, конечные точки P0 и P3 которой фиксированы в (0, 0) и (1, 1) соответственно. Координаты x P1 и P2 ограничены диапазоном [0, 1].
Вышеупомянутая кривая определяет, как выходные данные (ось y) будут вести себя в зависимости от времени (ось x). Каждая ось имеет диапазон [0, 1](или [0% 100%]). Если у нас есть анимация, которая длится две секунды (2s), то:
Если мы хотим анимировать left от 5px до 20px, то:
X, время, всегда ограничено [0 1]; однако Y может выходить за рамки [0 1]. Моя цель — отрегулировать P1 и P2, чтобы создать следующие кривые:
Вы можете подумать, что этого невозможно достичь, потому что, как указано в определении, P0 и P3 фиксированы (0,0) и (1,1) и это означает, что они не могут находиться на одной оси. Это правда, и мы воспользуемся некоторыми математическими приемами, чтобы «приблизительно» их «аппроксимировать».
Параболическая кривая
Давайте начнем со следующим определением: cubic-bezier(0,1.5,1,1.5). Это дает нам следующую кривую:
Наша цель — двигаться от (1,1) до (0,1) и делать то, что технически невозможно. Так что попробуем построить фейковою кривую.
Ранее мы говорили, что наш диапазон равен [0 1] (или [0% 100%]), поэтому давайте представим случай, когда 0% он очень близок к 100%. Если, например, мы хотим анимировать top от 20px (0%) до, 20.1px (100%) то мы можем сказать, что начальное и конечное состояния равны.
Хм, наш элемент вообще не двинется? Ну, он немного сдвинется, потому что значение Y превышает 20.1px( 100%). Но этого недостаточно, чтобы дать нам ощутимое движение:
CodePen Embed Fallback
Давайте обновим кривую и будем использовать cubic-bezier(0,4,1,4) вместо нее. Обратите внимание на то, что наша кривая стала намного выше, чем раньше:
CodePen Embed Fallback
Но все равно движения нет — даже если верхнее значение пересекает 3 (или 300%). Попробуем cubic-bezier(0,20,1,20):
CodePen Embed Fallback
Да! Он начал немного двигаться. Вы заметили изменение кривой каждый раз, когда мы увеличиваем значение? Это делает нашу точку (1,1) «визуально» ближе к тому моменту (0,1) когда мы уменьшаем масштаб, чтобы увидеть полную кривую, и это уловка.
Используя cubic-bezier(0,V,1,V) где V- какое-то очень большое значение, а начальное и конечное состояния очень близки (или почти равны), мы можем моделировать параболическую кривую. Пример стоит тысячи слов:
CodePen Embed Fallback
Я применил «волшебную» кубическую функцию Безье к анимации top, а также применил к ней линейную left. Это дает нам желаемую кривую.
Копаемся в математике
Для тех из вас, кто разбирается в математике, мы можем разбить это объяснение дальше. Кубический Безье можно определить по следующей формуле:
Каждая точка определяется следующим образом : P0 = (0,0), P1 = (0,V), P2 = (1,V), и P3 = (1,1). Это дает нам две функции для координат x и y:
V это наше большое значение и t находится в пределах допустимого диапазона [0 1]. Если мы рассмотрим наш предыдущий пример, Y(t) даст нам значение top в то время как X(t) — это время прогресса. Затем точки (X(t),Y(t)) будут определять нашу кривую.
Найдем максимальное значение Y(t). Для этого нам нужно найти значение t, которое нам даст Y’(t) = 0 (когда производная равна 0):
Y’(t) = 0 является квадратным уравнением. Я пропущу скучную часть и дам результат, который равен t = V — sqrt(V² — V).
Когда V имеет наибольшее значение, t будет равно 0.5. Значит, Y(0.5) = Max и X(0.5) будет равно 0.5. Это означает, что мы достигаем максимального значения в средней точке анимации, которая соответствует желаемой параболической кривой.
Кроме того, Y(0.5) даст нам, (1 + 6V)/8 и это позволит нам найти максимальное значение на основе V. И поскольку мы всегда будем использовать большое значение для V, мы можем упростить до 6V/8 = 0.75V.
Мы использовали V = 500 в последнем примере, поэтому максимальное значение будет равно 375(или 37500%), и мы получим следующее:
Исходное состояние (0): top: 200px
Конечное состояние (1): top: 199.5px
Или, выражаясь иначе:
CodePen Embed Fallback
Наш элемент касается вершины! Вот цифра, которая подводит итог только что проделанной нами математике:
Синусоидальная кривая
Мы воспользуемся почти тем же трюком, чтобы создать синусоидальную кривую, но с другой формулой. На этот раз мы будем использовать cubic-bezier(0.5,V,0.5,-V). Как и раньше, давайте посмотрим, как будет развиваться кривая, когда мы увеличим значение:
Я думаю, вы, наверное, уже поняли идею. Использование большого значения для V приближает нас к синусоидальной кривой.
CodePen Embed Fallback
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Вот еще один пример с непрерывной анимацией — настоящая синусоидальная анимация!
CodePen Embed Fallback
Математика
Давайте займемся математикой! Следуя той же формуле, что и раньше, мы получим следующие функции:
На этот раз нам нужно найти минимальное и максимальное значения для Y(t). Y’(t) = 0 даст нам два решения. После решения для этого:
Для большого значения у V нас есть t’=0.211 и t»=0.789. Это означает, что Y(0.211) = Max и Y(0.789) = Min. Это также означает, что X(0.211)= 0.26 и X(0.789) = 0.74. Другими словами, мы достигаем максимума в 26% случаев и минимума в 74% случаев.
Наша синусоидальная кривая также должна пересекать ось x (или Y(t) = 0) в половине случаев (или X(t) = 0.5). Чтобы доказать это, мы используем вторую производную от Y(t)- которая должна быть равна 0 и Y»(t) = 0.
Решением является 3V/(6V + 1), и для большого значения V результатом будет 0.5. Это дает нам Y(0.5) = 0 и X(0.5) = 0.5 что подтверждает, что наша кривая пересекает точку (0.5,0).
Теперь давайте рассмотрим предыдущий пример и попытаемся найти значение V, которое вернет top: 0%. У нас есть:
Исходное состояние (0): top: 50%
Конечное состояние (1): top: 49.9%
CodePen Embed Fallback
Как видите, наш элемент касается верхней части и исчезает внизу, потому что у нас есть следующая анимация:
Цифра для подведения итогов расчета:
И пример, иллюстрирующий все кривые вместе:
CodePen Embed Fallback
CodePen Embed Fallback
И ниже интерактивная демонстрация:
CodePen Embed Fallback
Возвращаясь к нашему примеру
Вернемся к нашему первоначальному примеру шара, движущегося в форме символа бесконечности. Я просто объединил две синусоидальные анимации, чтобы заставить их работать.
Если мы объединим то, что мы делали ранее, с концепцией множественной анимации, мы можем получить потрясающие результаты. Это снова начальный пример, на этот раз в виде интерактивной демонстрации. Измените значения и увидите волшебство:
CodePen Embed Fallback
Давайте пойдем дальше и добавим немного CSS Houdini. Мы можем анимировать сложное преобразования благодаря @property (но на данный момент CSS Houdini ограничен поддержкой Chrome и Edge).
CodePen Embed Fallback
Какие рисунки с его помощью можно делать? Вот несколько, что мне удалось сделать:
CodePen Embed Fallback
И версия без CSS Houdini:
CodePen Embed Fallback
Из этих примеров можно сделать несколько выводов:
Каждый ключевой кадр определяется с использованием только одного объявления, содержащего увеличение.
Положение элемента и анимация независимы. Мы можем легко разместить элемент в любом месте без необходимости настраивать анимацию.
Мы не производили расчетов. Нет множества углов или значений пикселей. Нам нужно только малое значение в ключевом кадре и большое значение функции cubic-bezier().
Всей анимацией можно управлять, просто регулируя значение продолжительности.
А как насчет перехода?
Тот же метод можно использовать и со свойством CSS transition, поскольку он следует той же логике, когда дело касается функций времени. Это здорово, потому что мы можем избежать использования ключевых кадров при создании сложного эффекта наведения.
Вот что я сделал без ключевых кадров:
CodePen Embed Fallback
Марио прыгает благодаря параболической кривой. Для создания анимации прыжка при наведении курсора нам не нужны были ключевые кадры. Синусоидальная кривая отлично справится со всей работой.
Вот еще одна версия Марио, на этот раз с использованием CSS Houdini. И да, он все еще прыгает благодаря параболической кривой:
CodePen Embed Fallback
Для удобства вот более интересные эффекты наведения без ключевых кадров (опять же, только для Chrome и Edge):
CodePen Embed Fallback
Вот и всё!
Теперь у вас есть несколько волшебных кривых cubic-bezier() и математика, стоящая за ними. Преимущество, конечно же, заключается в том, что такие пользовательские функции синхронизации позволяют нам создавать фантастические анимации без сложных ключевых кадров, к которым мы обычно стремимся.
Я понимаю, что не все разбираются в математике, и это нормально. Есть инструменты, которые могут помочь, например Ceaser Мэтью Лейна, который позволяет вам перетаскивать точки кривой, чтобы получить то, что вам нужно. И, если вы еще не добавили его в закладки, cubic-bezier.com — еще один полезный ресурс. Если вы хотите поиграть с кубиком Безье за пределами мира CSS, я рекомендую desmos, где вы можете увидеть некоторые математические формулы.
Независимо от того, как вы получаете свои cubic-bezier(), надеюсь, теперь вы имеете представление об их силе и о том, как они могут помочь в создании более приятного кода.
Автор: Temani Afif
Редакция: Команда webformyself.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Плавная трансформация | CSS свойство transition
Псевдокласс :hover позволяет элементам быть менее статичными, изменяя их свойства при наведении мышки.
Благодаря свойству transition (w3.org) можно сделать плавный переход между состояниями элемента.
Популярные сочетания transition с другими свойствами, например, opacity или transform
100 комментариев:
На самом деле мне приятно, что получается у читателей находить творческую нотку. Обращайся, помогу, чем смогу.
И, конечно, интересно взглянуть на ссылку 😉 Космо Мизраил Горыныч я на своём блоге попробую «проапгрейдить» снеговиков, так как мне тоже нужен этот эффект для моей галереи >_ NMitra Да, с фантазией у меня тоже туго, благо читатели всё время удивляют.
Очень немного и поверхностно. Ээээ. Из скрипта могу удалить ненужные фрагменты, тем самым настроив его под себя. С событием onclick недавно познакомилась.
Всё начинается с просьбы в комментарии и я лезу в дебри. А когда туда часто ходишь, дебри не кажутся такими уж ужасными.
В Firefox нормально, в Хроме кнопка «последние» (в CSS #footer-dva) «плывёт». Добавляю position: absolute, ситуация меняется, теперь в Firefox наблюдается кривобразие. В IE гаджеты друг под другом.
Пока идеи отсутствуют. Космо Мизраил Горыныч ну я тоже в ява-скрипте ни бум-бум)))))
посмотрел ваш код.
короче, я в коде окончательно запутался %.% и сотворил свою панель. конструкция гораздо проще, эффект тот же самый 🙂
Или сделала что-то вроде
Нужно, чтобы оба значения были указаны или в процентах или в величинах, например px. Есть ещё calc. Анонимный Спасибо большое за ответ!
В процентах таже картина, разворачивается, но без задержки.
А не подскажите может какойнить другой способ?
Нужно, чтоб при длинном тексте, часть теста скрывалась (видимая часть должна быть одинаковой), а при наведении курсора раскрывалась, но только на размер элемента (текста)
Спасибо. NMitra Смотрите в сторону позиционирования. Вам нужно показать поверх всего содержания текст или чтобы развёрнутый текст сдвигал остальной контент? Анонимный Пока сдвигает контент, но я не против, смотрится нормально, хочется пока чтоб показывало (разворачивало) только по размеру текста NMitra Ваш вопрос поняла, подумаю до конца недели, может завтра что и напридумаю. Анонимный Буду премного благодарен.
Спасибо за отзывчивость. NMitra Посмотрела, подумала. Разворачиваться плавно не будет. Можно другой какой-нибудь эффект или задать фиксированное значение или JavaScript
http://shopping.mk.ua/catalog/grupa/69 NMitra Нормально, как добились?
Adilet Melisov Спасибо классная статья! Спасибо за труд и ваше время! если еще будут статьи готов с радостью прочитать и научиться ))) NMitra Добро пожаловать! seoronin Наталья, отличная подборка примеров! Только у тебя нашел, как высоту div’а сделать плавной 🙂 NMitra Высота блока не должна быть указана в процентах. Пример:
Частично решает проблему max-height. Анонимный Сайт просто шикарный! Все что нужно, мне полезное, нашел здесь! NMitra Благодарю за отзыв! Богдан Казан Полезная статья для новичков) Анонимный Спасибо Вам большое. На Вашем сайте, всегда столько интересного и с примерами интересными и всё подробно рассказано. Действительно, БОЛЬШОЕ ВАМ спасибо. NMitra Благодарю! Очень радостно для меня было читать ваши слова! Анонимный Здравствуйте!
У меня вопросик.
Вот игрался, экспериментировал. И получилось. Что эффект. Смещение вниз. Вниз и наверх. Всё прекрасно. А вот в право и лево не едет, а перескакивает. Не подскажите почему. И можно ли сделать по диагонали. Например, из угла вытащить на середину.
А сайт Ваш просто замечательная находка для меня. Столько интересного и всё в одном месте. Спасибо Вам большое!
NMitra Здравствуйте, нужно начальное положение (top: 0; left:0;) и конечное (top: 50px; left: 50px;) http://jsfiddle.net/NMitra/d5jcmhxe/ Анонимный Извините за беспокойство. Всё нарыл, всё додумал. Добавил к top: 0; right:0; или left:0; И hovere right:сколько хочу; или left: сколько хочу;
И всё поехало. Только да в ИЕ не хочет, будем думать.
Спасибо Вам за такой хороший сайт. С его помощью становлюсь умнее. Спасибо.
Анонимный Во, пока я строчил и Вы ответили. Спасибо Вам большое. Анонимный Бомбочка, пацаны! Анонимный Здравствуйте!
Скажите пожалуйста как в примере с увеличением ДИВа как у Вас здесь в 2 раза.
Как сделать что бы увеличивался толь в одну сторону. Например в право.
Или чтобы. С верху в низ то есть по высоте.
Спасибо за вашу статью, очень интересна.
#uptocall <
border-radius: 50%;
width:110px;
height:110px;
animation: uptocall 1.5s linear infinite;>
#uptocall <
border-radius: 50%;
width:110px;
height:110px;
animation: uptocall 1.5s linear infinite;>

















