Анимации через выражения и маркеры в After Effects

Анимации через выражения и маркеры в After Effects

Статья в Notion, с ссылками на документацию и загрузку шаблонов анимации.

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

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

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

Если знаете как написать анимацию, можете переходить к маркерам

Функция анимации

Давайте представим, что мы хотим создать появление объекта. Самые ходовые анимации имеют линейный или плавный график функции именно для них уже созданы функции linear (линейная) и ease (плавная). Чтобы создать анимацию выражением нам необходимо открыть текстовое поле ввода. Для этого нужно нажать ЛКМ (левой клавишей мыши) с зажатым на клавиатуре alt по “часам” которые отвечают за создание первого ключа анимации, естественно для свойства Прозрачность (opacity).

Анимации через выражения и маркеры в After Effects
Анимации через выражения и маркеры в After Effects

В открытое поле вписываем функцию анимации. Рекомендую набирать, а не копировать, так лучше запоминается.

ease(time, 0, 1, 0, 100)

Функция имеет пять аргументов

  • Значение, по которому будет идти анимация, обычно это время (time);
  • Начало анимации, тот момент времени в который начинается, у нас нулевая секунда;
  • Окончание анимации, тот момент времени в который заканчивается, у нас первая секунда;
  • От какого значения, в нашем случае от 0%;
  • До какого значения, в нашем случае до 100%.

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

ease(time, inPoint, inPoint+1, 0, 100)

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

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

ease(time, inPoint, inPoint+1, 0, 100) - ease(time, outPoint-1, outPoint, 0, 100)

Обратите внимание, что во второй анимации сохраняется порядок значений свойств от нуля (0) до ста (100), та самая некоторая инверсия, которая слегка нарушает логику восприятия, так как логично было бы прокрутить анимацию от 100 до 0. Это происходит потому как мы отнимаем одну анимацию от другой.

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

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

Один из способов, заменить интересующие значения на Элементы управления выражения. Мы можем добавить ползунок который будет отображаться на панели Эффекты, где легко менять значения. Создайте себе Шаблон настроек анимации сразу с ползунком и забудьте о том как анимировать fade через ключи. Или скачайте уже готовый чуть ниже:

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

Маркер нам пригодиться как раз тогда, когда анимация возникает и заканчивается где-то по середине слоя. Продолжим добавив анимацию масштабирования после появления. Будем увеличивать на 15% и возвращать к прежнему состоянию уже известным способом. Новое выражение анимации вписываем в Масштабирование (scale). Здесь у нас два значения x и y, учитываем это. Для удобства добавим переменные, так код будет компактнее и легче повторяться.

a = ease(time, inPoint+1, inPoint+2, 100, 115) - ease(time, outPoint-2, outPoint-1, 0, 15); [a,a]

Обращаем внимание, что вторая анимация для уменьшения к прежнему значению имеет другие значения, но они простые. Представьте туже инверсию, но только так, что наше текущее значение (115) уже является началом, потому вторая анимация начинается с нуля (0) и соответственно изменение идет на 15%. Это особенность некоторых свойств.

Анимация начинается через секунду после появления и заканчивается за секунду до исчезновения.

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

s = transform.scale[0]/100; //Нивелирование масштабирования слоя a = ease(time, inPoint+1, inPoint+2, 100*s, 115*s) - ease(time, outPoint-2, outPoint-1, 0*s, 15*s); [a,a]

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

Следующий шаг — дополнить наглядностью, для этого мы привяжем анимацию к маркеру. Чтобы понять как он работает можно обратиться к API или нажав на стрелочку посмотреть иерархию метода.

Анимации через выражения и маркеры в After Effects

Добавляем маркер к слою и сразу назначаем ему продолжительность растягивая с зажатым alt. А теперь код.

m = marker.key(1).time; // Время начала маркера d = marker.key(1).duration; // Продолжительность маркера s = transform.scale[0]/100; //Нивелирование масштабирования слоя a = ease(time, m, m+1, 100*s, 115*s) - ease(time, m+d-1, m+d, 0*s, 15*s); [a,a]

Супер. Теперь наша анимация начинается там где начинается маркер и заканчивается там где он заканчивается. Все наглядно, маркер не скрывается в глубине слоя, на нем подписано что происходит от и до. Но всё это хорошо на раз, а что делать если анимацию нужно повторять, к примеру, цена выросла один раз и через несколько секунд должна вырасти ещё раз. Можно поступить весьма просто, сделать еще один маркер, а в выражении прописать ему следующий индекс, но это ручной труд и я его не поощряю. Значит нужно автоматизировать появления каждого маркера. нам поможет в этом Условие.

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

if (time > marker.key(1).time){ m = marker.key(1).time; d = marker.key(1).duration;}; if (time > marker.key(2).time){ m = marker.key(2).time; d = marker.key(2).duration;}; if (time > marker.key(3).time){ m = marker.key(3).time; d = marker.key(3).duration;}; s = transform.scale[0]/100; //Нивелирование масштабирования слоя a = ease(time, m, m+1, 100*s, 115*s) - ease(time, m+d-1, m+d, 0*s, 15*s); [a,a]

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

Я буду перебирать циклами while и for. И так как это завершение, то сразу форматируем и комментируем, чтобы было красиво. Вы можете оставить все в одну строку как мы начинали, это непринципиально. Я так писал, чтобы не засорять лишними знаками которые не влияют на работу выражения.

var i = 1, m = 1, d = 1; // чтобы не ругался до маркера // Назначение номеров маркерам while (i <= marker.numKeys) { if (time > marker.key(i).time) { m = marker.key(i).time; d = marker.key(i).duration; }; i+=1; } // Анимация var s = transform.scale[0] / 100; //Нивелирование масштабирования слоя var a = ease(time, m, m + 1, 100 * s, 115 * s) - ease(time, m + d - 1, m + d, 0, 15 * s); [a,a]
var m = 1, d = 1; // чтобы не ругался до маркера // Назначение номеров маркерам for (var i = 1; i <= marker.numKeys; i += 1) { if (time > marker.key(i).time) { m = marker.key(i).time; d = marker.key(i).duration; } } // Анимация var s = transform.scale[0] / 100; //Нивелирование масштабирования слоя var a = ease(time, m, m + 1, 100 * s, 115 * s) - ease(time, m + d - 1, m + d, 0, 15 * s); [a,a]

Если вы хотите разделить анимации по названию маркеров, например, чтобы маркеры с описанием “масштаб” отвечали за анимацию масштабирования, добавьте соответствующее условие к его проверке, где marker.key(’масштаб’).
Property — numKeys (docsforadobe.dev)

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

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

Анимируйте и процветайте 🖖

77
5 комментариев

Пытался изучить AE, очень сложно((

Ответить

Очень нравится ваш подход от простого к сложному. Так реально легче усваивать материал

Ответить

Оно лучше усваивается, когда понимаешь что, как и от чего. В отличии от если бы просто дал код и расписал что в нём.

Ответить

Ждем часть 2 для продвинутой анимации ))

Ответить

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

Ответить