Подборка экспрешнов для After Effects
Собрал список выражений для АЕ, которые упрощают мне работу. Совсем простых в стиле loopOut() или wiggle (.4,6) здесь не будет, но и ничего экстрасложного тоже.
Своих экспрешнов здесь всего парочка. Большинство я брал откуда-то и переписывал по чуть-чуть под себя, так что, у чужих экспрешнов поставлю ссылку на авторов.
Плашка за текстом
Создать шейповый квадратик, а сверху отдельным слоём добавить текст;
Применить к параметру size у шейпа:
margin_width = 60;
margin_height = 40;
text_width = thisComp.layer(index-1).sourceRectAtTime().width;
text_height = thisComp.layer(index-1).sourceRectAtTime().height;
box_width = text_width + margin_width*2;
box_height = text_height + margin_height*2;
[box_width, box_height]
Если текст в несколько строк, то к position у шейпа добавьте этот экспрешн. Без него тоже всё будет работать, но придётся вручную подгонять позицию плашки за текстом.
x = value[0];
y = content("Rectangle 1").content("Rectangle Path 1").size[1]/2;
[x,y]
К остальным экспрешнам
Анимируемый wiggle
Простой способ заанимировать wiggle. Используем для этого два слайдера: первый отвечает за частоту, второй за амплитуду. Анимировать лучше только амплитуду.
Добавить эффект Slider Control на слой с экспрешном и продублировать его. Применить к любому параметру:
w_freq = effect("Slider Control")("Slider");
w_amplitude = effect("Slider Control 2")("Slider");
wiggle(w_freq,w_amplitude)
Цикличный wiggle
Благодаря этому экспрешну, wiggle начинается и заканчивается в одной и той же точке.
Если вдруг цикл не работает, то это скорей всего из-за того, что луп не успевает прийти в изначальное состояние за отведённое время. Просто сделайте loopTime побольше или freq почаще
freq = 1;
amp = 65;
startTime = 0; // На какой секунде начинается луп
loopTime = 3; // Сколько секунд идёт
t = (time+startTime) % loopTime;
wiggle1 = wiggle(freq, amp, 1, 0.5, t);
wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopTime);
linear(t, 0, loopTime, wiggle1, wiggle2)
Прикрепить шейп к одной стороне
Применить к position, изменять size у шейпа:
stickTo = "left"; // top, bottom, right or left
chosenShape = content("Rectangle 1").content("Rectangle Path 1");
if (stickTo == "top"){
x = chosenShape.position[0];
y = chosenShape.position[1]+chosenShape.size[1]/2;
}
else if (stickTo == "bottom"){
x = chosenShape.position[0];
y = chosenShape.position[1]-chosenShape.size[1]/2;
}
else if (stickTo == "right"){
x = chosenShape.position[0]-chosenShape.size[0]/2
y = chosenShape.position[1]
}
else if (stickTo == "left"){
x = chosenShape.position[0]+chosenShape.size[0]/2;
y = chosenShape.position[1]
}
[x,y]
Риг для катящегося круга и квадрата
Катящийся круг
Применить к rotation, анимировать position:
transform.position[0]-(content("Ellipse 1").content("Ellipse Path 1").size[0]/2)-transform.position[0]/2
Катящийся квадрат
Работает как с шейпами, так и со слоями и композициями. Если квадрат катится неправильно — изменить значение Slider Control.
Добавить на слой с экспрешном эффект Slider Control. Применить экспрешн к position, анимировать rotation:
targetLayer = thisLayer;
squareSize = targetLayer.sourceRectAtTime().width;
squareDiag = (Math.sqrt(2)*squareSize)/2/3.5;
try{
squareOffset = effect("Slider Control")("Slider");
}
catch(err) {
squareOffset = 0;
}
rot=transform.rotation;
scl=transform.scale[0]/100;
w=(squareSize/2)*scl;
r=(degreesToRadians(rot))*2;
t=transform.position;
[t[0]+w*rot/45,t[1]-(Math.abs((squareDiag+squareOffset)*Math.sin(r)))*scl];
На основе экспрешна от Mikey Borup
Ежесекундные ступенчатые повороты
Замена time*n. Только вместо плавного поворота — ступенчатый. Чаще всего пригождается, чтобы сделать анимацию секундной стрелки, шестерёнок или других похожих механизмов.
Применить к rotation:
angle = 15; // Угол поворота в секунду
rotateDuration = 10; // Длительность поворота в кадрах
rotateDurationFr = rotateDuration/(1/thisComp.frameDuration);
wholeSecond = Math.floor(time);
startAngle = wholeSecond * angle;
ease(time, wholeSecond, wholeSecond + rotateDurationFr, startAngle, startAngle + angle)
Управляемые ступенчатые повороты
Практически то же самое, что и выше. Но с чуть большим количеством настроек.
Применить к rotation:
angle = 15; // Угол поворота
rotateDuration = 6; // Длительность поворота в кадрах
timeStop = 5; // Длительность остановки между поворотами
offset = 0; // Сдвиг начального положения в кадрах
fr = timeToFrames(time)+offset;
cycle = timeStop+rotateDuration;
n = Math.floor(fr/cycle);
cur_phase = fr-n*cycle;
if((cur_phase)>timeStop){
angle*n+(cur_phase-timeStop)*angle/rotateDuration;
}
else{
angle*n;
}
Постоянный масштаб при скейле
Если привязать один объект к другому и начать скейлить родительский, то оба слоя будут увеличиваться. Этот экспрешн не даёт дочернему слою изменять масштаб, он просто будет двигаться по позишну.
Применить к scale слоя, у которого должен быть постоянный масштаб:
s = [];
ps = parent.transform.scale.value;
for (i = 0; i < ps.length; i++){
s[i] = value[i]*100/ps[i];
}
s
Переключатель по чекбоксу
Меняет одно значение параметра на другое по нажатию на чекбокс.
Добавить эффект Checkbox Control на слой с экспрешном;
Применить к любому параметру:
if (effect("Checkbox Control")(1) == 0) 0 else 100
Луп для шейпов
Обычный loopOut() не работает с шейпами, но зато работает этот экспрешн.
Применить к path у шейпа:
try{
pingPong = false; // Поставьте true, если нужен pingPong
timeStart = thisProperty.key(1).time;
duration = thisProperty.key(thisProperty.numKeys).time-timeStart;
quant=Math.floor((time-timeStart)/duration);
if(quant<0) quant = 0
if(quant%2 == 1 && pingPong == true){
t = 2*timeStart+ (quant+1)*duration - time;
}
else{
t = time-quant*duration;
}
}
catch(err){
t = time;
}
thisProperty.valueAtTime(t)
Range Mapper
Добавить эффект Slider Control на слой с экспрешном;
Применить к любому параметру:
input = effect("Slider Control")("Slider");
inputLow = 0;
inputHigh = 100;
outputLow = 466;
outputHigh = 618;
linear(input,inputLow,inputHigh,outputLow,outputHigh)
Обводка независимая от скейла
Сохраняет постоянную обводку у шейпов при изменении масштаба.
Применить к «Stroke Width» у шейпа:
value / length(toComp([0,0]), toComp([0.7071,0.7071])) || 0.001;
Счётчики
Почему-то часто использую счётчики в анимациях, поэтому здесь будет подборка сразу из шести. Сначала три самых простых.
1) Обычный счётчик
toFixed(1) — количество цифр после запятой;
Добавить эффект Slider Control на слой с экспрешном;
Применить к «Source Text» у текста:
parseFloat(effect("Slider Control")("Slider")).toFixed(1)
2) Счётчик с запятыми вместо точек
Полезно в анимациях для неанглоязычных стран, где используется запятая в качестве десятичного разделителя вместо точки. Если нужен похожий сетап с большим количеством настроек, то он вот здесь.
c = parseFloat(effect("Slider Control")("Slider")).toFixed(1);
c.toString().replace(".", ",")
3) Счётчик с дополнительными знаками
"+"+parseFloat(effect("Slider Control")("Slider")).toFixed(1)+"%"
4) Счётчик с заменой 1 на 001
При zerosAmount = 3 счёт будет идти вот так: 000, 001 … 011 … 111.
zerosAmount = 3;
var slider = effect("Slider Control")("Slider");
function padStart(string, targetLength, character) {
string = (string instanceof String) ? string : string.toString();
targetLength = targetLength >> 0;
character = character || ' ';
while (string.length < targetLength) {
string = character + string;
}
return string;
};
if (slider >= 0) {
zeroAmount = zerosAmount + 1;
paddedString = padStart(parseFloat(slider.value).toFixed(0), zerosAmount, '0');
}
else {
paddedString = '-0'+padStart(parseFloat(slider.value).toFixed(0)*-1, zerosAmount, '0');
}
paddedString;
На основе экспрешна от Tomas Sinkunas
5) Счётчик с разрядами
Заменяет 500000 на 500 000.
num = parseFloat(effect("Slider Control")("Slider")).toFixed(0);
str = isNaN(num) ? "" : (num * 1 + "");
str.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ');
6) Счётчик для больших чисел
Счётчик, привязанный к Slider Control, не идёт дальше 1 000 000. Поэтому если нужны большие числа — приходится использовать эффект Angle Control.
Добавить эффект Angle Control на слой с экспрешном;
Применить к «Source Text» у текста:
number = Math.round(effect("Angle Control")("Angle")/360);
n="" + number;
s="";
for(i=0, l=n.length; i<l; i++){
if(s && s!="-" && (l-i)%3 ==0)
s+=" ";
s += n[i];
}
s;
Пара мелочей
И, под конец, 4 полезных мини-выражения, которые часто пригождаются.
1) Привязка к слою выше или ниже
Это не полноценный экспрешн, а только его часть. Вместо того, чтобы привязывать один слой к другому напрямую, иногда удобнее привязывать к слою, который стоит выше или ниже, слоя с экспрешном.
index+1 — если нужна привязка к слою ниже
thisComp.layer(index-1)
2) Постоянно ускоряющиеся повороты
Попробуйте добавить к rotation:
time*time*time*time
3) Ключи для time*n
Добавляет постоянное движение, но оставляет возможность ставить ключи.
value+time*11
4) Привязка эффекта к слою
Чтобы Gradient Ramp не слетал при перемещении слоя, добавьте этот экспрешн на Start и End:
toComp(value)
Похоже, это все выражения, которыми я пользуюсь на постоянной основе. Всего получилось 23.
На всякий случай, собрал их в проект и прикрепил к статье.
Спасибо, бро!
Вот это да! Спасибо!
Очень полезная статья!
Огромное спасибо! Годные сеттинги
Получилось очень даже хорошо. Все экспрешены были интересны. Спасибо за подбор!
Спасибо большое!
Спасибо большое, это очень полезно! Особенно для новичков!
Здравствуйте возник вопрос по index. Скажите к какому параметру вы присваивали этот экспрешн?
Я применял его к position у слоя.
Вот так выглядел экспрешн:
thisComp.layer(index-1).transform.position
Благодаря этому, слой с экспрешном копирует позицию того слоя, который находится над ним на таймлайне.
Например, здесь Shape 03 повторяет позицию Shape 02: https://i.imgur.com/2PkxNTr.png
Спасибо большое, во многом очень помоги!
очень удобно, спасибо за труды!
Блин! И почему нет разбора того экспрешена, который мне нужен(