Подборка экспрешнов для 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.
На всякий случай, собрал их в проект и прикрепил к статье.