Анимация переходов между RecyclerView и ViewPager. Анимация переходов между двумя фрагментами

Эволюцией CSS3 стала возможность задавать поведение для переходов и анимации. Фронтенд-разработчики много лет просили реализовать эти взаимодействия внутри HTML и CSS, без использования JavaScript или Flash. Теперь их мечта сбылась.

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

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

Переходы

Ключевые кадры анимации

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

@keyframes slide { 0% { left: 0; top: 0; } 50% { left: 244px; top: 100px; } 100% { left: 488px; top: 0; } }

Вендорные префиксы в правиле @keyframes

Правило @keyframes должно быть с вендорными префиксами, так же, как и все другие свойства transition и animation . Префиксы для @keyframes выглядят следующим образом:

  • @-moz-keyframes
  • @-o-keyframes
  • @-webkit-keyframes

Анимация выше называется slide , состояния начинаются сразу же после открытия правила @keyframes . Разные контрольные точки ключевых кадров задаются помощью процентов, начиная с 0% и работая до 100%, с промежуточной точкой на 50%. При желании вместо 0% и 100% могут быть использованы ключевые слова from и to . Кроме 50% также могут быть указаны дополнительные контрольные точки. Свойства элементов для анимации перечислены внутри каждой контрольной точки, left и top в приведённом выше примере.

Важно отметить, как и с переходами, могут быть анимированы только отдельные свойства. Подумайте, как вы могли бы переместить элемент сверху вниз, например. Попытка анимировать от top: 0 до bottom: 0 не будет работать, потому что анимация может применять только переход в пределах одного свойства, а не от одного свойства к другому. В этом случае элемент необходимо анимировать от top: 0 до top: 100% .

animation-name

После того, как объявлены ключевые кадры для анимации, они должны быть назначены для элемента. Для этого используется свойство animation-name с именем анимации из правила @keyframes , как значение свойства. Декларация animation-name применяется к элементу, для которого должна быть задана анимация.

Stage:hover .ball { animation-name: slide; }

Использования одного свойства animation-name при этом недостаточно. Кроме того, необходимо объявить свойство animation-duration и значение, чтобы браузер знал, как долго должна длиться анимация до завершения.

animation-duration, функция времени и animation-delay

После того, как вы объявили свойство animation-name для элемента, анимация ведёт себя подобно переходам. Она включают в себя длительность, функцию времени и задержку при желании. Сперва анимации требуется длительность, объявленная с помощью свойства animation-duration . Как и в случае с переходами, длительность может быть задана в секундах или миллисекундах.

Stage:hover .ball { animation-name: slide; animation-duration: 2s; }

Функция времени и задержка могут быть объявлены с помощью свойств animation-timing-function и animation-delay , соответственно. Значения этих свойств подражают и ведут себя так же, как это делается с переходами.

Stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; }

Анимация ниже должна вызвать отскок ball один раз при перемещении вправо, но только при наведении курсора на stage.

@keyframes slide { 0% { left: 0; top: 0; } 50% { left: 244px; top: 100px; } 100% { left: 488px; top: 0; } } .stage { height: 150px; position: relative; } .ball { height: 50px; position: absolute; width: 50px; } .stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; }

Настройка анимации

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

animation-iteration-count

По умолчанию, анимация запускает свой цикл один раз от начала до конца, а затем останавливается. Чтобы анимация повторялась много раз может быть использовано свойство animation-iteration-count . Значения для него включают целое число или ключевое слово infinite . С помощью целого числа анимация будет повторяться столько раз, сколько указано, в то время как ключевое слово infinite будет повторять анимацию бесконечно и никогда не остановится.

Stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-iteration-count: infinite; }

animation-direction

Кроме возможности установить, сколько раз анимация повторяется, вы можете также объявить направление, в котором анимация завершается, с помощью свойства animation-direction . Значения этого свойства включают в себя normal , reverse , alternate и alternate-reverse .

Значение normal воспроизводит анимацию, как и намеревалось, от начала до конца. Значение reverse воспроизводит анимацию точно наоборот, чем это определено в правиле @keyframes , таким образом, начиная со 100% и работая в обратном направлении до 0%.

Значение alternate воспроизведёт анимацию вперёд, а затем назад. В ключевых кадрах это включает выполнение вперёд от 0% до 100%, а затем в обратном направлении от 100% до 0%. Используя свойство animation-iteration-count можно ограничить количество раз, когда анимация работает вперёд и назад. Счёт начинается с 1, когда анимация проходит вперёд от 0% до 100%, а затем добавляется 1, когда анимация проходит в обратном порядке от 100% до 0%. Объединение в общей сложности двух итераций. Значение alternate также инвертирует любые функции времени при воспроизведении в обратном направлении. Если анимация использует значение ease-in идущее от 0% до 100%, то затем использует значение ease-out идущее от 100% до 0%.

И, наконец, значение alternate-reverse сочетает оба значения alternate и reverse , запуская анимацию назад, а затем вперёд. Значение alternate-reverse начинается со 100% и выполняется до 0%, а затем снова обратно до 100%.

Stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-iteration-count: infinite; animation-direction: alternate; }

animation-play-state

Свойство animation-play-state позволяет анимации воспроизводиться или остановиться на паузу, с помощью ключевых слов running и paused , соответственно. Когда анимация снимается с паузы, она возобновляет работу из текущего состояния, а не начинается снова с самого начала.

В приведённом ниже примере свойство animation-play-state устанавливается на паузу, когда stage активен при щелчке по нему. Обратите внимание на то, как анимация временно приостанавливается, пока вы не отпустите кнопку мыши.

Stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-iteration-count: infinite; animation-direction: alternate; } .stage:active .ball { animation-play-state: paused; }

animation-fill-mode

Свойство animation-fill-mode определяет, как элемент должен быть стилизован - до, после или до и после запуска анимации. Свойство animation-fill-mode принимает четыре значения ключевых слов, включая none , forwards , backwards и both .

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

Значение forwards сохранит стили, объявленные в последнем указанном ключевом кадре. На эти стили, однако, могут повлиять значения свойств animation-direction и animation-iteration-count , меняя, где анимация заканчивается.

Значение backwards будет применять стили первого заданного ключевого кадра, до того, как анимация будет работать. Включает применение этих стилей в течение всего времени, что может быть задано в animation-delay . Значение backwards также может зависеть от значения свойства animation-direction .

Наконец, значение both применит поведение сразу от обоих значений forwards и backwards .

Stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-fill-mode: forwards; } .stage:active .ball { animation-play-state: paused; }

Сокращённое свойство animation

К счастью анимация , подобно переходам, может быть записана в сокращённом формате. Это получается с помощью одного свойства animation вместо нескольких объявлений. Порядок значений в свойстве animation должен быть следующий: animation-name , animation-duration , animation-timing-function , animation-delay , animation-iteration-count , animation-direction , animation-fill-mode и, наконец, animation-play-state .

Stage:hover .ball { animation: slide 2s ease-in-out .5s infinite alternate; } .stage:active .ball { animation-play-state: paused; }

Ресурсы и ссылки

  • Understanding CSS3 Transitions на A List Apart
  • CSS Cubic-Bezier Builder на Rob LaPlaca
  • The Guide To CSS Animation: Principles and Examples на Smashing Magazine
  • Using CSS Animations на Mozilla Developer Network

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

Немного об ингредиентах нашего рецепта демо-проекта

В основном компоненте у нас есть небольшая навигация и routing-outlet для организации вывода страниц.

И плюс два компонента с контентом которые будут служить нам страницами.

Для начала нам потребуется модуль BrowserAnimationsModule -- 1шт.
Подключим его в файле app.module.ts.

Не стоит забывать, что для корректной работы в браузерах, которые не поддерживают Web Animations API, нужен полифил web-animations .

Для этого, в консоле проекта пропишем: npm install --save web-animations-js и в файле polyfills.ts раскомментируем строку:

И после этого подключаем его в основном модуле:


Добавляем заранее приготовленную анимацию по вкусу:)

Для начала немного подкорректируем наш роутинг чтоб при переходе между страницами мы еще и передавали состояние для анимации (state):

После чего в основном компоненте app.component.ts добавим функцию для получения этого состояния getState(), а также подключим и задекларируем нашу анимацию:

Теперь забиндим анимацию и подвяжем ее под результат функции getState() в основном темплейте:

На данном этапе может возникнуть вопрос “зачем?” Ведь у нас, в анимации stateChangeExpr прописан как: "* <=> *", а это по сути любая смена состояний. Но как показывает практика, в проектах редко бывает только одна анимация. Множество разных анимации переходов по страницах как раз будут основаны на состояниях (state). Вам нужно будет прописывать только stateChangeExpr для нужного перехода.

Рассмотрим один из примеров. Допустим вам нужна уникальная анимация только при переходе с страницы “контакты” на страницу “новостей”. В роутинге вы будете передавать state со значениями “contacts” и “news” соответственно. Тогда значение stateChangeExpr в анимации для этого конкретного случая будет "contacts => news".

На данном этапе у нас уже есть почти готовое блюдо:

Но идеальное блюдо требует не только идеального приготовления, но и внимания к деталям.

По-этому, на определенные объекты пропишем дополнительную анимацию. Пусть это будут абзацы на странице Page1.

Добавляем к ним класс:

После этого дописываем анимацию.

В 6 строке мы описали статическое поведение наших абзацев при переходе на страницу с ними. А в строках 16-20 поведение абзацев после перехода на страницу.

В нашем рецепте мы использовали stagger() , который с заданным интервалом переберет наши абзацы и применит к ним анимацию.

Хочу обратить внимание на то, что при переходе на другие страницы, элементов с классом .anim может не быть. А при компиляции query(":enter .anim" выдаст ошибку, именно поэтому нужно использовать надстройку { optional: true } которая будет игнорировать отсутствующую выборку.

Теперь можем любоваться супер-блюдом, которое у нас получилось:)

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

В общем на этом все, надеюсь материал был полезен.

Bon appétit!

** На момент написания статьи использовался @angular/cli: 1.7.3 с последней версией Angular 5.2.9. Код также будет поддерживаться и на версиях Angular 2 и выше.
Отдельная благодарность Gerard Sans за содействие при написании статьи.

На прошлой неделе был «праздник в Веларибо» – получила долгожданное для многих обновление до версии 7.1, которое добавило какие-то функции и, дескать, убрало какие-то баги. Но главной особенностью обновления стало увеличение скорости работы. Говорят, что на «яблоках» все стало просто летать. Дорогое «Велабаджо», хватит мыть посуду – как устроить себе такой же праздник читайте под катом!

За что мы любим Android? Конечно, за его гибкость. Система не только открыта для разного рода сторонних «украшений», но и сама имеет некоторые функции, позволяющие пользователю существенно изменить впечатления от использования устройства.

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


Для начала необходимо получить доступ в пункт меню «Параметры разработчика». Для этого зайдите в настройки своего смартфона и перейдите в пункт меню «Об устройстве», там найдите строку с информацией о номере сборки и нажмите на нее 7 раз. Если вы не можете найти какой-то из пунктов меню, то погуглите как активировать «Параметры разработчика» конкретно на вашей модели телефона.

Затем перейдите в появившийся в настройках пункт «Параметры разработчика» и найдите там следующие настройки:

  • Масштаб анимации окна
  • Масштаб анимации перехода
  • Шкала длительности аниматора

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

По умолчанию здесь выставлены значения «1х» — измените их на «0.5х». Вуаля!

Эти Android-настройки изменят ваш пользовательский опыт, ускорив переходы между окнами интерфейса. То есть сделав то же самое, что и обновление iOS. К тому же, это никоим образом не должно влиять на расход батареи. Хотя, если вы используете старую модель телефона с медленным процессором, вы можете увидеть некоторые подрагивания.

Пробуйте и делитесь в комментариях своими впечатлениями!

Одним из краеугольных камней в Material design являются осмысленные движения между экранами. Lollipop предоставляет поддержку этих анимаций в форме фреймворка переходов между Activity и Fragment. Поскольку статей по данной теме не так много, я решил написать свою собственную!

Наш конечный продукт будет достаточно прост. Мы будем делать приложение-галерею с котиками. При нажатии на изображение будет открываться экран с подробностями. Благодаря фреймворку переход из сетки изображений в окно с подробностями будет сопровождаться анимацией.

Если вы желаете увидеть, что получилось - готовое приложение находится на GitHub .

Поддержка предыдущих версий Android?

У меня есть для вас две новости: хорошая и плохая. Плохая новость заключается в том, что до Lollipop данный фреймворк не работает. Не смотря на это, проблема решается методами библиотеки поддержки с помощью которой вы можете реализовать анимированые переходы доступные в API 21+.

В статье будут использоваться функции из библиотеки поддержки для обеспечения перемещения контента.

Имена переходов

Для ассоциации View на первом экране и его двойника на втором нужна связь. Lollipop предлагает использовать свойство “transition name ” для связи View между собой.

Существует два способа добавления имени перехода (transition name ) для ваших View:

  • В коде можно использовать ViewCompat.setTransitionName() . Конечно, вы так же можете просто вызвать setTransitionName() , если поддержка начинается с Lollipop.
  • Для добавления в XML, используйте атрибут android:transitionName .
Важно отметить, что внутри одного макета (layout ), имена переходов должны быть уникальны. Держите это в уме при организации переходов. Указывая transition name для ListView или RecyclerView задаст это же имя и для всех остальных элементов.

Настройка FragmentTransaction

Настройка FragmentTransactions должна быть вам очень знакомой:

GetSupportFragmentManager() .beginTransaction() .addSharedElement(sharedElement, transitionName) .replace(R.id.container, newFragment) .addToBackStack(null) .commit();
Чтобы указать какую View будем передавать между фрагментами - используем метод addSharedElement() .

Переданная View в addSharedElement() это View из первого фрагмента, которую вы хотите разделить (share ) со вторым фрагментом. Имя перехода тут является именем перехода в разделенной (shared ) View во втором фрагменте.

Настройка анимации перехода

Наконец-то пришел момент, когда мы зададим анимацию перехода между фрагментами.

Для shared элементов:

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

Вы так же можете анимировать переходы для всех non-shared View. Для этих View, используйте setEnterTransition() , setExitTransition() , setReturnTransition() , и setReenterTransition() в соответствующих фрагментах.

Каждый из этих методов принимает один параметр Transition предназначенный для выполнения анимации.

Создавать анимацию мы будем очень просто. Мы используем наш кастомный transition для передвижения изображения (об этом чуть позже), и исчезание ( Fade) при выходе.

Классы анимации перехода

Android предоставляет некоторые готовые анимации переходов, что подходят для большинства случаев. Fade выполняет анимацию исчезновения. Slide анимирует переход появления/исчезновения скольжением из угла экрана. Explode анимация подобная взрыву, изображение движется от краев экрана. И наконец, AutoTransition заставит изображение исчезать, двигаться и изменять размер. Это лишь некоторые примеры из пакета перемещений, их на самом деле намного больше!

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

Public class DetailsTransition extends TransitionSet { public DetailsTransition() { setOrdering(ORDERING_TOGETHER); addTransition(new ChangeBounds()). addTransition(new ChangeTransform()). addTransition(new ChangeImageTransform())); } }
Наш кастомный переход есть ни что иное как набор из трех готовых переходов собранных вместе:

Все вместе

Код который в итоге у нас получился оказался достаточно простым:

DetailsFragment details = DetailsFragment.newInstance(); // Note that we need the API version check here because the actual transition classes (e.g. Fade) // are not in the support library and are only available in API 21+. The methods we are calling on the Fragment // ARE available in the support library (though they don"t do anything on API < 21) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { details.setSharedElementEnterTransition(new DetailsTransition()); details.setEnterTransition(new Fade()); setExitTransition(new Fade()); details.setSharedElementReturnTransition(new DetailsTransition()); } getActivity().getSupportFragmentManager() .beginTransaction() .addSharedElement(holder.image, "sharedImage") .replace(R.id.container, details) .addToBackStack(null) .commit();
Вот и все! Простой способ реализации анимации переходов между двумя фрагментами готов!

В CSS3 есть две техники визуализации, которые соревнуются за ваше внимание: анимация (Animations) и переходы (Transitions) (примечание: в статье будут использованы русские варианты названий этих техник). В этой статье мы попробуем выявить сходства и различия этих техник, чтобы вы понимали, когда лучше использовать тот или иной способ.

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

Сходства

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

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

На этом сходства заканчиваются и начинаются…

Различия

Различия между анимацией и переходами проявляются, когда вы начинаете их запускать. Различия также состоят в том, насколько легко/сложно запрограммировать переход/анимацию и тем, как легко всем этим управлять через JavaScript . Давайте исследуем эти различия более подробно.

Запуск

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

Переход запускается, когда изменяется какое-либо CSS-свойство. Наиболее часто встречается использование псевдокласса:hover для изменения значения свойства CSS:

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

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

С помощью имеющегося свойства, анимацию можно перевести в статус паузы (pause ), что означает, что она будет неактивна до тех пор, пока свойство не будет переведено в статус запущено (running ). Консорциум W3C решил удалить это свойство, поэтому сейчас его уже не существует.

Зацикливание

Это очень просто. Анимация может быть легко зациклена с помощью установки свойства animation-iteration-count. Вы можете задать любое фиксированное число для повтора анимации, которое пожелаете:

animation-iteration-count: 5;

Если вы хотите, чтобы ваша анимация повторялась бесконечно, то установите следующее значение:

animation-iteration-count: infinite;

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

Определение промежуточных точек / ключевых кадров (keyframes)

С помощью анимации вы можете определить ключевые кадры, которые дадут вам больше контроля над значениями CSS-свойств, нежели просто начальная и конечная точка:

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

При использовании переходов у вас нет достаточного контроля над конечным результатом:

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

Явное определение анимируемых свойств

Следующая вещь, о которой я хочу рассказать, это явное определение анимации и переходов применительно к значениям CSS-свойств.

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

Например, у вас есть следующий переход:

#mainContent { background-color: #CC0000; transition:background-color .5s ease-in; } #mainContent:hover { cursor: pointer; background-color: #000000; width:500px; }

В коде выше, указаны различные значения свойств background-color и width . Однако, явно определен переход только для свойства background-color. Это значит, что браузер будет анимировать только изменение свойства background-color.

Если же необходимо, чтобы анимированы были оба свойства — и background-color , и width — следует это явно определить:

#mainContent { background-color: #CC0000; transition:background-color .5s ease-in, width .5s ease-in } #mainContent:hover { cursor: pointer; background-color: #000000; width: 500px; }

Что насчет параметра «all» при определении перехода?

В действительности, нет необходимости определять каждое анимируемое свойство при объявлении перехода. Вы можете облегчить себе жизнь, если будете использовать значение «all » вместо описания конкретных свойств, например: transition: all .5s ease-in . Однако так поступать не рекомендуется, потому что такой подход наносит ущерб производительности.

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

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

keyframes imageSlide { 0% { left: -150px; } 20% { left: 50px; height: 200px; } 80% { left: 200px; height:300px; } 100% { left: 600px; background-color:#FFFFFF; } }

В примере выше, свойства height и background-color будут плавно изменяться в соответствии с определенными ключевыми кадрами, даже если какое-то свойство до этого не было объявлено!

Взаимодействие с JavaScript

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

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

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

Когда дело доходит до взаимодействия JavaScript и анимации/переходов, то вы почти всегда будете использовать именно переходы. При связке анимация-JavaScript… практически невозможно заставить анимацию нормально работать.

Анимация очень специфична для создания связки с JavaScript. Команда @keyframes четко определяет последовательность анимации, которая запускается сразу после загрузки страницы. Попытка изменить заданную анимацию через JavaScript потребует выполнения очень сложной последовательности шагов, включая модификацию самого стилевого правила @keyframes. Если вы когда-нибудь пытались изменять CSS-свойства внутри стилевого правила, то вы, скорее всего, представляете сложность данной процедуры.

Противоположностью анимации в данном смысле является переход. Переходы не настолько четко определены. Переход запускается, когда определенное свойство изменяется. Изменение этого свойства может быть полностью задано через CSS:

#myElement { background-color: #FFF; transition: background-color .2s ease-in; } #myElement:hover { background-color: #000; }

Это изменение может быть выполнено через JavaScript: вы можете изменить CSS-свойство, которое «слушает » ваш переход, обратившись к inline-стилю :

var myElement = document.querySelector("#myElement"); myElement.style.backgroundColor = "333";

Переход не обращает внимания на то, каким способом изменяются значения «слушаемых» свойств. Пока значение изменяется, переход будет работать. Это значит, что вы можете делать много интересных вещей с интерактивными сценариями, не связанными жестко заданными начальными и конечными точками. Желаемые значения свойств для перехода могут быть заданы через JavaScript.

Чтобы лучше понять, о чем идет речь, посмотрите вот этот простой пример :

Кликните в любой точке серой формы и круг переместится в эту точку.

Этот пример работает достаточно просто. Перемещение круга обрабатывается с помощью CSS-перехода. Однако, координаты точки, в которую надо переместить круг, передаются через JavaScript. Так как переход «слушает » координаты, то любое их изменение ведет к запуску этого перехода. Конечный результат работы именно такой, каким он и был задуман.

Самое примечательное, что не требуется писать JavaScript-код для реализации самого перехода. И, наконец, так как поддержка переходов встроена в стандарт CSS и, соответственно, в браузер, анимация происходит очень плавно.

Эта дружба между переходами и JavaScript очень сильна, поэтому вам стоит использовать это преимущество на полную катушку.