Полезные фишки After Effects
Анимация смотрится более интересной, если колебания не просто останавливаются, пусть и плавно, а всё таки колеблются. Для этого можно использовать скрипт.
Конечно я такое не пишу, а копирую и вставляю. Поэтому я оставлю это тут, чтоб посмотреть в случае надобности. А может ещё кому пригодится.
n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time){
n--;
}
}
if (n == 0){
t = 0;
}
else{
t = time - key(n).time;
}
if (n > 0){
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
amp = .025;
freq = 2.0;
decay = 3.0;
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}
else{
value;
}
Данное выражение нужно вставить в Expression в параметрах Position, Scale или другие. Таким образом при движении или увеличении масштаба, в ключевом кадре будут колебания.
А вот ещё одно выражение для затухающих колебаний. Предыдущее почему-то не работает с перемещением точки по двум осям. А вот это работает:
amp = .1;
freq = 1.0;
decay = 5.0;
n = 0;
time_max = 4;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time){
n--;
}}
if (n == 0){ t = 0;
}else{
t = time - key(n).time;
}
if (n > 0 && t < time_max){
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}else{value}
Bounce в тексте
Создаем или используем уже готовый текстовой слой.
Заходим в свойства текста: Text -> Animate -> Любой параметр для анимации
Будет создан аниматор, внутри него ваше свойство и селектор (Range Selector по стандарту). Удаляем стандартный селектор и нажимаем добавить новый (меню рядом с аниматором – справа) – Selector -> Expression
Открываем параметры Expression Selector и в Amount добавляем наше выражение.
freq = 1; //частота / frequency
decay = 6; //распад / decay
duration = 0.25; //продолжительность / duration
retard = textIndex*thisComp.frameDuration*1;
t = time - (inPoint + retard);
startVal = [100,100,100];
endVal = [0,0,0];
if (t < duration){
linear(t,0,duration,startVal,endVal);
}else{
amp = (endVal - startVal)/duration;
w = freq*Math.PI*2;
endVal + amp*(Math.sin((t-duration)*w)/Math.exp(decay*(t-duration))/w);
}
источник
Ещё вариант bounce для текста
delay = 0.1;
myDelay = delay*textIndex;
t = (time - inPoint) - myDelay;
if (t >= 0){
freq =1;
amplitude = 150;
decay = 6;
s = amplitude*Math.cos(freq*t*2*Math.PI)/Math.exp(decay*t);
[s,s]
}else{
value
}
источик
Как заменить файл в композиции с сохранением всех его движений, эффектов и т.д
1) Выделяем слои, которые надо подвергнуть замене
2) из окна проекта тянем нужный файл, которым подменяем источник, зажав при этом Alt.
источник
Пропорциональный виггл
w=wiggle(1,20); [w[0],w[0]]
источник
виггл к одному значению переменной
w = wiggle(2,50); [value[0],value[0],w[1]]
[value[0],value[0],wiggle(1,2)[0]]
источник
разный виггл к двум значениям переменной Position
ww = wiggle(.8,10);
wh = wiggle(.8,1);
[ww[0],wh[1]]
Одновременно wiggle и LoopOut
L = loopOut(type = "pingpong", numKeyframes = 0);
ww = wiggle(.3,10);
wh = wiggle(.3,100);
L + [ww[0],wh[1]] - value
Если нужно сделать разный виггл и ссылаться на слой в композиции с поправкой:
L = loopOut(type = "pingpong", numKeyframes = 0);
ww = wiggle(.3,10);
wh = comp("name-comp").layer("name-layer").effect("name-effect")("Output 1");
L + [ww[0],wh+1780] - value
Как обратиться в expression к другой композиции
comp("name-comp").layer("control").effect("Color font end text")("Color")
Выражение для движения по спирали от края к центру
Применяется к Position
//Moves things in a spiral (apply to position)
center=[thisComp.width/2,thisComp.height/2];
rMax = 240; //maximum radius
decay = 0.3; //decay
freq = 6; //frequency
aStart = 0; //start angle offset
aRate = 220; //rotation rate
offsetFactor = 1000; //smoothness
r = rMax/Math.exp(time*decay);
a = degreesToRadians(aStart + aRate*time);
offset = (r/offsetFactor)*Math.sin(freq*time*Math.PI*2);center + [Math.cos(a),Math.sin(a)]*(r + offset);
Округление чисел
Например при создании счётчика, чтоб округлить до целого числа
Вставить в слайдер:
Math.round(value)
Округление со знаком после точки
В source текста вставить expression
parseFloat(effect("Slider Control")("Slider")).toFixed(4)
Автоматический зум вначале и в конце слоя
//Snap zoom in and out: apply to scale
snapScale = 1000; //percent of scale to zoom
trans = 4; // transition time in frames
trans = trans * thisComp.frameDuration;
inTrans = easeOut(time, inPoint, inPoint + trans, [snapScale,snapScale], [0,0]);
outTrans = easeIn(time, outPoint, outPoint - trans, [0,0], [snapScale, snapScale]);
value+ inTrans + outTrans
Для Z
zoom = 5000; //distance to zoom
trans = 4; // transition time in frames
trans = trans * thisComp.frameDuration;
inTrans = easeIn(time, inPoint, inPoint + trans, [0,0,zoom], [0,0,0]);
outTrans = easeOut(time, outPoint, outPoint - trans*2, [0,0,0], [0,0,zoom]);
value+ inTrans - outTrans
Резкие быстрые движения по Y
Например, для создания глитч-эффекта, путём анимации таким образом цветного слоя
// Y Axis Jitter
probability = 8 ; //higher is less likely
pos = 50;
val = random(-probability-2, 1);
m = clamp(val, 0, 1);
y = wiggle(10, pos*m)-position;
value + [0, y[1]]
Автоматический размер подложки для текста (субтитров)
Применить выражение к Size шейпа
textLayer = thisComp.layer("text");//наш текстовый слой
bbox = textLayer.sourceRectAtTime(time+.01,true);//bounding box вокруг текста
[bbox.width*textLayer.scale[0]/100,bbox.height*textLayer.scale[1]/100]+[50,50]
Ещё вариант
Создать шейп, а над ним текстовый слой
В 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 и Loop одновременно
Подходит, например, для точки в эффектах, когда использовать нуль для подобных целей затруднительно
L = loopOut ("pingpong" ) ; //you can also put "pingpong" instead of "cycle" for your loop
W = wiggle ( 1, 200 ) ; //3 is the times per second, 30 is the number of pixels it will vacillate
L + W - value ;
Bounce (отскоки)
e = .7; //высота отскока
nMax = 3; //количество отскоков
g = 5000; //гравитация
n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time) n--;
}
if (n > 0){
t = time - key(n).time;
v = -velocityAtTime(key(n).time - .001)*e;
vl = length(v);
if (value instanceof Array){
vu = (vl > 0) ? normalize(v) : [0,0,0];
}else{
vu = (v < 0) ? -1 : 1;
}
tCur = 0;
segDur = 2*vl/g;
tNext = segDur;
nb = 1; // number of bounces
while (tNext < t && nb <= nMax){
vl *= e;
segDur *= e;
tCur = tNext;
tNext += segDur;
nb++
}
if(nb <= nMax){
delta = t - tCur;
value + vu*delta*(vl - g*delta/2);
}else{
value
}
}else
value
источник
Если одно значение меньше Х, тогда выводить другое
Мне нужно было сделать виггл под музыку. Однако музыка была не всегда. При этом когда музыки не было мне нужно было, чтоб слой шатался при постоянном виггл.
t = comp("name-comp").layer("music").effect("music")("param");
if (comp("name-comp").layer("music").effect("music")("param") < 1) t =5;
t;
wiggle(1,t/5)
Если значение музыки меньше comp("name-comp").layer("music").effect("music")("param"), тогда выводим 5. если нет, выводим 20 или больше
Изменение размера шейпов с одной стороны (сбоку) через Size с сохранением пропорции Roundness
В Anchor Point шейпа написать выражение
Слева направо
w = content("Rectangle 1").content("Rectangle Path 1").size[0];
[w/2, value[0]]
w - слева направо
-w - справа налево
h = content("Rectangle 1").content("Rectangle Path 1").size[1];
[value[0], -h/2];
h - сверху вниз
-h - снизу ввех
Плавная смена цвета
Color Balance (HLS) - анимация Hue
Условия
if ( a > b ) {
"A Wins!";
} else {
"B Wins!";
}
Если a больше b, то выводится первая строка
Если это не так, то есть a меньше b, то выводится вторая строка
так же можно использовать другие варианты
< - меньше
== - равно
Для чекбокса (галочки)
Например, нужно отображать слой или скрывать при нажатии на галочку.
В параметре прозрачности (opacity) прописать:
if (путь до эффекта чекбокс == 1) 0 else 100;
то есть, если галочка проставлена (== 1), то значение параметра прозрачности будет = 0. а если галочка не проставлена, то = 100
живой пример со ссылкой на слой settings, эффект "Checkbox" с названием "full image" в композиции "slide-show"
if (comp("slide-show").layer("settings").effect("full image")("Checkbox") == 1) 0 else 100;
Внутренняя обводка для шейпа
Add --- Offset Paths
Прикрепить параметр Amount к Stroke Width шейпа и дописать /-2
источник
Прозрачность слоя относительно положения камеры
Выражение применяется к Opacity 3д слоя
startFade = 500; // Начало затухания слоя 500 пикселей до камеры
endFade = 1500; // Конец затухания слоя 1500 пикселей до камеры
try
{ // Проверка, есть ли камера в композиции
C = thisComp.activeCamera.toWorld([0,0,0]);
}
catch(err)
{ // Если камеры нет, то симулируем камеру с фокусным расстоянием 50мм
w = thisComp.width * thisComp.pixelAspect;
z = (w/2)/Math.tan(degreesToRadians(19.799));
C = [0,0,-z];
}
P = toWorld(anchorPoint);
d = length(C,P);
linear(d,startFade,endFade,100,0)
источник
Обратное действие в зависимости от скорости
Например на Rotatiion повесить следующий expression
thisComp.layer("path").transform.position.velocity[0]/-200;
Он ссылается на позицию слоя path
Счётчик с округлением и дополнительными символами
В source text прописать следующее
Math.floor(effect("Slider Control")("Slider")) + " руб."
Счётчик с разделением на разряды
Применить следующее выражение к source text для привязки к слайдеру
num = parseFloat(effect("Slider Control")("Slider")).toFixed(0);
str = isNaN(num) ? "" : (num * 1 + "");
str.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ');
Теперь тысячные будут разделяться пробелом
Счётчик с постоянным количеством цифр
Применить следующее выражение к source text для привязки к слайдеру
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;
zerosAmount - это количество цифр. В данном примере цифры будут выглядеть как 001 002 020, то есть если в числе меньше 3 цифр, то будут добавляться нули
Счётчик для миллионов
Применить следующее выражение к source text для привязки на этот раз к Angle control
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;
Зацикленный wiggle для разных значений
loopTime = 3;
t = time % loopTime;
wx1 = wiggle(.3, 150, 1, .5, t);
wx2 = wiggle(.3, 150, 1, .5, t - loopTime);
wy1 = wiggle(.3, 160, 1, .5, t);
wy2 = wiggle(.3, 160, 1, .5, t - loopTime);
wz1 = wiggle(.3, 500, 1, .5, t);
wz2 = wiggle(.3, 500, 1, .5, t - loopTime);
linear(t, 0, loopTime, [wx1[0],wy1[1],wz1[2]], [wx2[0],wy2[1],wz2[2]])
Если значения 2, например, без оси Z, тогда соответствующий параметр - wz - следует убрать как минимум из последней строчки из выражения
Для одного значения, например, для Rotation, выражение может выглядеть так:
loopTime = 15;
t = time % loopTime;
wx1 = wiggle(.1, 20, 1, .5, t);
wx2 = wiggle(.1, 20, 1, .5, t - loopTime);
linear(t, 0, loopTime, [wx1], [wx2])
loopTime - это время цикла в секундах. То есть длина композиции
Эффект управления количеством кадров в секунду (FPS)
Effects - Time - Posterize Time
Мягкие края для текста и других слоёв
Делать мягкие края можно разными способами. Я у Энрю Крамера увидел интересный вариант со стилем слоя
Нужно применить стиль слоя Inner Glow со следующими параметрами:
Blend mode: normal
Technique: precise
Size: 6
Изменение параметра одного значения, относительно другого
Есть какой-то меняющийся параметр, например Position, Scale или что-либо ещё. Для примера возьмём Scale, который меняется от 0 до 100
Задача: изменять другой параметр, например Slider Control, относительного того параметра Scale. Причём не просто привязав к тому Scale и меняя Slider Control с 0 до 100, а через интерполяцию. То есть чтоб, например, если Scale = 0, то Slider Control пусть будет = 25. И когда Scale = 100, то Slider Control пусть будет = 65
Таким образом можно менять нужное значение относительно другого значения в заданном диапазоне без использования ключевых точек
Для этого нужно в параметре изменяемого значения прописать следующее выражение:
linear(time, t1, t2, val1, val2)
Для конкретно текущего примера:
linear(thisComp.layer("name-layer").transform.scale[0], 0, 100, 25, 60)
Вместо linear можно easeOut
источник
Постоянная ширина обводки, независимо от scale
Прописать выражение в «Stroke Width»:
value / length(toComp([0,0]), toComp([0.7071,0.7071])) || 0.001;
Привязка положения эффекта к слою
Применять следующее выражение к эффекту, где используется Position. Например, Radial Blur -- Center, а так же Start и End в Gradient Ramp или в Offset Turbulence в Fractal Noise
toComp(value)
Таким образом положение эффекта не будет менять при перемещении слоя. Обычно чтоб такого достичь приходилось делать прекомпоз
Печатающийся текст с мигающим курсором
Быстрый вариант с маркерами
В Source текстового слоя вставить выражение
//put this expression for the 'Source Text' value on your text layer, and add 4 markers on the layer : 'cursorStart', 'textStart', 'textStop', 'cursorStop'
cursor="|";
cursorBlink = 1; //seconds
txt = value;
timeIn = thisLayer.inPoint; //seconds
txtSize = text.sourceText.length;
animateText = true;
showCursor = true;
//check if required markers exists
try{
textStart = marker.key('textStart').time;
textStop = marker.key('textStop').time;
}catch(e){
AnimateText = false;
}
//check if required markers exists
try{
cursorStart = marker.key('cursorStart').time;
cursorStop = marker.key('cursorStop').time;
}catch(e){
showCursor = false;
}
if (animateText){
duration = textStop - textStart; //type-on duration in seconds
txtIdx = linear(time, textStart, textStop, 0, txtSize);
txt = substr(0,txtIdx)
}
if (showCursor){
F = Math.round( (time + cursorStart) % cursorBlink );
if ( (time > cursorStart) && (time < cursorStop) && (F==1) ) {
txt += cursor;
}
}
txt;
При этом создать 4 маркера 'cursorStart', 'textStart', 'textStop', 'cursorStop'.
Вариант со слайдером ниже. Можно регулировать скорость набора текста, останавливать печатание.
В Source текстового слоя вставить выражение
txt = value;
timeIn = thisLayer.inPoint; //seconds
txtSize = text.sourceText.length;
cursor="|";
cursorBlink = 1; //seconds
txtComplete = 100; //percents - add a slider 'txtComplete' on your layer to animate this value
animateText = true;
showCursor = true;
//check if required markers exists
try{
txtComplete = effect("txtComplete")("Slider");
}catch(e){
AnimateText = false;
}
//check if required markers exists
try{
cursorStart = marker.key('cursorStart').time;
cursorStop = marker.key('cursorStop').time;
}catch(e){
showCursor = false;
}
if (animateText){
txtIdx = txtSize / 100 * txtComplete;
txt = substr(0,txtIdx)
}
if (showCursor){
F = Math.round( (time + cursorStart) % cursorBlink );
if ( (time > cursorStart) && (time < cursorStop) && (F==1) ) {
txt += cursor;
}
}
txt;
Создать Slider Control с именем txtComplete. А так же два маркера 'cursorStart', 'cursorStop'.
Слайдером регулируется количество текста от 0 до 100. Маркерами регулируется начало и конец мигания курсора
cursor="|"; - символ для мигающего курсора
источник
Обратный отсчёт времени (Таймер времени)
Создать текстовый слой, добавить в него Слайдер
В source текстового слоя прописать выражение
t=parseInt(effect("Slider Control")("Slider"));
s=t;
m=t;
h=t;
while (s>(60-1)) s-=60;
while (m>(3600-1)) m-=3600;
m=Math.floor(m/60)
while (h>(60*60*24-1)) h-=60*60*24;
h=Math.floor(h/60/60)
FixLen(h)+":"+FixLen(m)+":"+FixLen(s);
function FixLen (input)
{
numDigits = 2;
out=input.toString();
while (out.length < numDigits) out = "0" + out;
return out;
}
Далее настраивать отсчёт через ключевые кадры слайдера. Можно делать как обратный отсчёт, так и движение времени вперёд.
Если часы не нужны, а только минуты и секунды, из выражения следует убрать
FixLen(h)+":"+
источник
Запуск по одному маркеру
Например, на слое проставлены маркеры для создания эффектов синхронно под музыку
На слое SK проставить маркеры - каждый маркер - это триггер для срабатывания
Создать композицию, в которой сделать нужные действия. Например создать Adjustment Layer с нужным эффектом, например Brightness & Contrast - для создания эффекта яркости в нужный момент. Проанимировать эффект от 0 до нужного значения и затем затихания до 0.
В этой композиции на том же уровне (выше) со слоем SK поставить Collapse Transformations (солнышко), чтоб Adjustment Layer работал из композиции. В Time Remapping добавить выражение
markerLayer = thisComp.layer("SK"); // слой с маркерами
dur = 1.0;
startOffset = 0;
delay = -0.3; // >0 = позже, <0 = раньше
if (markerLayer.marker.numKeys > 0) {
m = markerLayer.marker.nearestKey(time);
if (m.time > time && m.index > 1) {
m = markerLayer.marker.key(m.index - 1);
}
mt = m.time + delay; // ← ключевой момент
dt = time - mt;
if (dt > 0) {
dt < dur ? startOffset + dt : startOffset + dur;
} else {
startOffset; // ещё не стартовали
}
} else {
time;
}
Ещё вариант, когда нужно по маркерам сделать, например, прозрачность от 0 до Хи снова до 0
Также в Time Remapping прописать
markerLayer = thisComp.layer("SK"); // слой с маркерами
framesBefore = 2; // за сколько кадров до "срабатывания"
fadeOutDur = 0.8; // спад после
delay = -0.3; // >0 позже, <0 раньше
preTime = framesToTime(framesBefore);
t = time;
if (markerLayer.marker.numKeys > 0) {
m = markerLayer.marker.nearestKey(t);
if (m.time > t && m.index > 1) {
m = markerLayer.marker.key(m.index - 1);
}
mt = m.time + delay; // ← добавили delay
start = mt - preTime;
end = mt + fadeOutDur;
if (t >= start && t <= mt) {
ease(t, start, mt, 0, 100);
} else if (t > mt && t <= end) {
ease(t, mt, end, 100, 0);
} else {
0;
}
} else {
0;
}
Таймер обратного отсчёта в секундах без ключевых кадров
Данный скрипт работает только на основе выражения и длины слоя - ключевые кадры не нужны. В текстовый слой в "source text" вставить выражение:
t = Math.max(0, Math.ceil(outPoint - time));
"До следующего слайда: " + t + " сек."


