Заключение
Тема диплома «Скриптописание в среде Adobe After Effects в сфере видеодизайна» сейчас является очень актуальной и активно развивающейся. В ходе разработки проекта была освоена новая программная среда Adobe After Effects, а именно: была проведена большая работа по изучению среды, знакомство с дополнительными средствами программы, изучение встроенного языка программирования для создания различных функций, предназначенных для работы с графическими элементами и их анимацией. Были исследованы существующие тенденции в сфере видеодизайна, созданы необходимые эффекты, был разработан шаблон-макет и был реализован в конкретной практической работе. На его основе был дополнительно создан видеоролик об СПБ КИТ. Были расширены знания программной среды и языка программирования. Был разобран и экономический эффект работы.
В ходе работы над дипломным проектом был создан проект-макет на тему инфографики в Adobe After Effects, который будет упрощать и автоматизировать работу как дизайнера, так и обычного пользователя для создания видеороликов. Выполненный проект полностью соответствует поставленному техническому заданию.
В качестве результата выполненной работы был получен проект формата «.aep» с организованной рабочей файловой структурой, а также готовый видеоролик.
В дальнейшем планируется еще более глубокое изучение программной среды, ее возможностей и языка программирования для написания уникальных функций-эффектов, как мощного инструмента в работе дизайнера.
Список используемой литературы
Рудольф Арнхейм - «Искусство и визуальное восприятие»
А.Г. Соколов - "Монтаж"
http://www.adobe.com/support/aftereffects
http://www.videocopilot.net
http://www.greyscalegorilla.com
http://www.jjgifford.com/expressions/
http:// ru.wikipedia.org
http://www.wikipedia.org
Приложение 1: Исходный программный код
• Экспрешн, отвечающий за появление графического объекта в композиции - эффект затухающего колебания. Было использовано большое количество вариантов данной функции много раз для различных объектов.
amp = .06; //амплитуда колебания
freq = 3.0; //сила колебания
decay = 8.0; //время затухания
if (numKeys > 0)//выполнение с начала установленного ключа
{
n = nearestKey(time).index;//индексация ключа анимации
if (key(n).time > time)//проверка прошедшего времени (по-секундно)
{
n--;//значение колебание уменьшается
}
}
if (n==0)//если значение колебания равно 0
{
t=0;//приостанавливается выполнения колебания
}
else
{
t=time-key(n).time;//значение ключа анимации уменьшается во времени
}
if (n > 0) //если значение колебания больше нуля
{
v = velocityAtTime(key(n).time - 0.04);//вычисление колебания граф. элемента во времени (продолжительность одного кадра = 0.04)
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
//получение значения параметра в соответствии с математической функцией (y=sin*2*PI/exp(x))
}
else
{
value;
}
• Экспрешн, отвечающий за основной таймер (просчет времени) в композиции (отсчет с нуля) main + cc + sound.
rate = 1; //скорость таймера (1 – обычная скорость)
clockStart = 0; //начало отсчета
function padZero(n) //конвертирование целого числа, например: число «7» превратится в «07»
{
if (n < 10)
return "0" + n
else
return "" + n
}
clockTime = clockStart + rate*(time - inPoint); //вычисление значения таймера
if (clockTime < 0) //проверка таймера на отрицательное значение, в случае чего будет установлен знак «-»
{
sign = "-";
clockTime = -clockTime;
}else{
sign = "";
}
t = Math.floor(clockTime); //округление значения времени
hr = Math.floor(t/3600); //вычисление значения часа
min = Math.floor((t%3600)/60); // вычисление значения минуты
sec = Math.floor(t%60); // вычисление значения секунды
ms = clockTime.toFixed(3).substr(-3); //вычисление значения миллисекунд
sign + "[" + padZero(hr) + ":" + padZero(min) + ":" + padZero(sec) + "." + ms + "]" //вывод полученного текста в качестве таймера на основе полученных значений
• Экспрешн, отвечающий за плавное хаотичное движение камеры, установленной в различных композициях (эффект морской качки).
xAmp = 3; //высота колебаний
xFreq = .3; //количество колебаний за секунду
xSpeed = 150; //скорость волны колебания
wl = xSpeed/xFreq; //вычисление длины волны
phaseOffset = ((position[0]%wl)/wl)*2*Math.PI; //смещение позиции
y = xAmp*Math.sin(2*Math.PI*xFreq*time + phaseOffset); //вычисление «y» позиции
value + [0,y] //присвоение значения
• Экспрешн, отвечающий за плавное движение элементов графика в пространстве по осям X и Y в композиции Grafik.
segMin = .3; //минимальная продолжительность движения
segMax = .7; //максимальная продолжительность движения
minVal = 0; //минимальное значение
maxVal = 10; //максимальное значение
end = 0; //переменная окончания движения
j = 0; //переменная для вычисления значения генератора случайных чисел
while ( time >= end) //проверка временного значения
{
j += 1;
seedRandom(j,true); //генерирование случайного числа
start = end; // начало выполнения функции
end += random(segMin,segMax); увеличение значения на случайное число в диапазоне значений продолжительности движения
}
endValx = random(minVal,maxVal) + 1050; //получение конечного значения «x»
endValy = random(minVal,maxVal) + 500; // получение значения конечного «y»
seedRandom(j-1,true);
dummy=random(); //выбрасываемое значение
startValx = random(minVal,maxVal) + 1050; //получение конечного значения «x»
startValy = random(minVal,maxVal) + 500; // получение конечного значения «y»
y = position[1];
ease(time,start,end,[startValx,startValy],[endValx,endValy]) //присвоение значения в соответствии с «мягкими» ключами анимации
• Экспрешн, отвечающий за движение объектов композиции Network в 3d пространстве.
xAmplitude = 4; //амплитуда движения
xFrequency = .24; //частота движения
xSpeed = 120; //скорость движения
wl = xSpeed/xFrequency; //длина волны движения
phaseOffset = ((position[0]%wl)/wl)*2*Math.PI; //смещение позиции
y = xAmplitude*Math.sin(2*Math.PI*xFrequency*time + phaseOffset);
//вычисление позиции по оси «y»
value + [0,y] //присвоение значения
• Экспрешн, позволяющий соединять между собой два конца (например ,1-й и 2-й) луча эффекта Beam примененного к слою, который используется в композиции Network.
Эти два экспрешена были применены для соединения восьмы элементов рисунка локальной сети.
layer = thisComp.layer("1") //выбор нужного нуль объекта
layer.toComp([50,50,0]) //соединение с точкой с выравниванием 50х50
---
Определение второй точки
layer = thisComp.layer("2")
layer.toComp([50,50,0])
• Экспрешн, анимирующий график в композиции Graph_Fade.
amp = .09; //амплитуда колебания
freq = 2.5; //сила колебания
decay = 5.0; //время затухания
if (numKeys > 0) //выполнение с начала установленного ключа
{
n = nearestKey(time).index;//индексация ключа анимации
if (key(n).time > time)//проверка прошедшего времени (по-секундно)
{
n--;//значение колебание уменьшается
}
}
if (n==0)//если значение колебания равно 0
{
t=0;//приостанавливается выполнения колебания
}
else
{
t=time-key(n).time;//значение ключа анимации уменьшается во времени
}
if (n > 0) //если значение колебания больше нуля
{
v = velocityAtTime(key(n).time - 0.04);//вычисление колебания граф. элемента во времени (продолжительность одного кадра = 0.04)
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}
else
{ value; }
• Экспрешн, создающий текст в виде сложного бинарного кода (в виде нулей и единиц).
stroki = 22; //количество строк
stolbiki = 80; //количество столбцов
frequency = 5; //частота смены чисел
posterizeTime(frequency); //вычисление количества кадров в секунду
randMin = Math.pow(2,stolbiki); //вычисление минимального значения появления
randMax = randMin*2; //вычисление максимального значения появления
str = ""; //текст на данный момент ничего присваивает
for(i =0; i < stroki; i++)
{
str += random(randMin,randMax).toString(2).substr(1) + "\r"; //вывод числовых значений в текстовом слое
}
str
• Экспрешн, создающий связь между параметрами различных слоев.
thisComp.layer("[Particles]").effect("Particular")("Color")
• Экспрешн, создающий затухающее колебание для движения камеры в основной композиции
amp = .02; //амплитуда
freq = 1.0; //частота, сила
decay = 8.0; //затухания
if (numKeys > 0) //выполнение с начала установленного ключа
{
n = nearestKey(time).index;//индексация ключа анимации
if (key(n).time > time)//проверка прошедшего времени (по-секундно)
{
n--;//значение колебание уменьшается
}
}
if (n==0)//если значение колебания равно 0
{
t=0;//приостанавливается выполнения колебания
}
else
{
t=time-key(n).time; //значение ключа анимации уменьшается во времени
}
if (n > 0) //если значение колебания больше нуля
{
v = velocityAtTime(key(n).time - 0.04); //вычисление колебания граф. элемента во времени (продолжительность одного кадра = 0.04)
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}
else
{
value;
}
• Экспрешн, создающий небольшую систему частиц, движущихся по осям «X» и «Y».
columns = 10; //количество столбцов
tHold= .2; //задержка движения по времени, должна быть меньше tMin
tMin = .5; //минимальное время цикла
tMax = 1; //максимальное время цикла
gap = this_comp.width/columns; //разрыв между столбцами
origin = [gap,gap];
xGrid = columns - 1; //определение таблицы для системы частиц
yGrid = Math.floor(this_comp.height/gap) - 1;
start = 0; //начальное значение движения
end = 0; //конечное значение движения
j = 1; //переменная начала цикла
while (time >= end)
{
j += 1; //запуск цикла для движения
seedRandom(j,true); //генератор случайных чисел
start = end;
end += random(tMin,tMax); //формирование нового движения
}
targetX = Math.floor(random(0,xGrid)); //новая точка по оси X, которой будет стремиться элемент
targetY = Math.floor(random(0,yGrid)); //новая точка по оси X, которой будет стремиться элемент
seedRandom(j-1,true);
x = random(); //выбрасываемое значение для X
oldX = Math.floor(random(0,xGrid)); //определение старой точки по X
oldY = Math.floor(random(0,yGrid)); // определение старой точки по Y
//определение перемещения объекта в зависимости от временной задержки
if(targetX == oldX && targetY == oldY) //проверка условия совпадения значений старой и новой точки
{
origin + [oldX,oldY]*gap;
}
else
if (time - start < tHold)
{
origin + [oldX,oldY]*gap;
}
Else
{
deltaX = Math.abs(targetX - oldX);
deltaY = Math.abs(targetY - oldY);
xTime = (end - start - tHold)*(deltaX/(deltaX + deltaY));
yTime = (end - start - tHold)*(deltaY/(deltaX + deltaY));
if (time < start + tHold + xTime)
{
startPos = origin + [oldX,oldY]*gap;
targetPos = origin + [targetX,oldY]*gap;
easeOut((time - start - tHold)/xTime, startPos, targetPos); //начало движения объекта с мягким ключом на выходе
}
Else
{
startPos = origin + [targetX,oldY]*gap;
targetPos = origin + [targetX,targetY]*gap
easeIn((time - start - tHold - xTime)/yTime, startPos, targetPos); //конец движения объекта с мягким ключом на входе
}
}
• Экспрешн, позволяющий создать систему частиц, используя только стандартную форму в виде сферы
origin = [10,10,10]; //описываем стандартный размер массива (таблица)
dimX = 10; //к-во ячеек по X
dimY = 10; //к-во ячеек по Y
dimZ = 10; //к-во ячеек по Z
gap = 50; //максимально расстояние между ячейками
gridRate = 500; //скорость движения частиц
holdTime = .1; //максимальная задержка по времени
//описываем необходимые переменные, заранее обнулив их
start = 0; //начальный отсчет
startX = 0; //начальная позиция по X
startY = 0; //начальная позиция по Y
startZ = 0; //начальная позиция по Z
endX = 0; //конечная позиция по X
endY = 0; //конечная позиция по Y
endZ = 0; //конечная позиция по Z
deltaX = 0; //разница в смещении между началом и концом по X
deltaY = 0; //разница в смещении между началом и концом по Y
deltaZ = 0; //разница в смещении между началом и концом по Z
end = 0; //конец отсчета
j = 0;
while (time >= end)
{
seedRandom(j,true); //генератор случайных чисел
//задаем начальные позиции элемента
startX = Math.floor(random(dimX))*gap + origin[0]; //по X
startY = Math.floor(random(dimY))*gap + origin[1]; //по Y
startZ = Math.floor(random(dimZ))*gap + origin[2]; //по Z
j +=1;
произойдет новое перемещение объекта
seedRandom(j,true) //генератор случайных чисел
start = end; //присваиваем значению "end" значение "start" для просчета
конечной позиции элемента
//аналог кода, как у start
endX = Math.floor(random(dimX))*gap + origin[0];
endY = Math.floor(random(dimY))*gap + origin[1];
endZ = Math.floor(random(dimZ))*gap + origin[2];
deltaX = Math.abs(endX - startX);
deltaY = Math.abs(endY - startY);
deltaZ = Math.abs(endZ - startZ);
//теперь конечная позиция будет менятся в каждом новом цикле
end += (deltaX + deltaY + deltaZ)/gridRate + 3*holdTime;
}
p1 = start + deltaX/gridRate; //определено случайное расположение объекта и первое движение по X
p2 = p1 + holdTime; //второе движение c задержкой
p3 = p2 + deltaY/gridRate; //третье со смещением по Y
p4 = p3 + holdTime; //четвертое с задержкой
p5 = p4 + deltaZ/gridRate; //пятое со смещением по Z
//проверка на порядок действий (порядок движения) и движение по-этапное
if (time < p1)
{
ease(time,start,p1,[startX,startY,startZ],[endX,startY,startZ]) //изменение позиции с мягким ключом анимации
}
else if (time < p2)
{
[endX,startY,startZ] //первое смещение
}
else if (time < p3)
{
ease(time,p2,p3,[endX,startY,startZ],[endX,endY,startZ]) //третье движение
}
else
if (time < p4)
{
[endX,endY,startZ] //четвертое
}
else
if (time < p5){
ease(time,p4,p5,[endX,endY,startZ],[endX,endY,endZ]) //пятое
} else
{
[endX,endY,endZ]
}
//движение элемента теперь будет происходить в случайном порядке по сетке по направлениям X,Y и Z
• Экспрешн, создающий эффект спирографа
r1 = 43; //радиус 1
r2 = -14; //радиус 2
o = 53; //смещение
speed = 15; //скорость
s = 2.5; //размер
r = r1 + r2; //общ. радиус
x = r*Math.cos(time*speed) - (r2 + o)*Math.cos(r*time*speed/r2); //движение по X
y = r*Math.sin(time*speed) - (r2 + o)*Math.sin(r*time*speed/r2); //движение по Y
[s*x + thisComp.width/2, s*y + thisComp.height/2]; //присвоение значения по X и Y
• Экспрешн, создающий эффект счетчика
val = thisComp.layer("Slider").effect("Slider Control")("Slider"); //переменной val присваивается значение вспомогательного эффекта Slider Control, присвоенного к текстовому слою
numDec = 0; // количество цифр справа
numDigit = 2; // количество цифр слева
if (val < 0) //проверка на отрицательное значение
sign = "-" else sign = ""; //если значение меньше 0, то перед числом поставится знак -
s = Math.abs(val).toFixed(numDec); //получение фиксированного значения
while (s.length < numDigit + numDec + 1)
s = "0" + s; //присвоение значения
sign + s //вывод числа
• Экспрешн, анимирующий ориентацию камеры в композиции Network
xAmplitude = 5; //амплитуда движения
xFrequency = .23; //частота движения
xSpeed = 122; //скорость движения
wl = xSpeed/xFrequency; //длина волны движения
phaseOffset = ((position[0]%wl)/wl)*2*Math.PI; //смещение позиции
y = xAmplitude*Math.sin(2*Math.PI*xFrequency*time + phaseOffset);
//вычисление позиции по оси «y»
y = xAmplitude*Math.sin(2*Math.PI*xFrequency*time + phaseOffset);
//вычисление позиции по оси «x»
value + [x,y] //присвоение значения
ПРИЛОЖЕНИЕ 2: Результаты работы программы

Рис. 22. Кадр 1 готового видеоролика

Рис. 23. Кадр 2 готового видеоролика

Рис. 24. Кадр 3 готового видеоролика

Рис. 25. Кадр 4 готового видеоролика

Рис. 26. Кадр 5 готового видеоролика

Рис. 27. Кадр 6 готового видеоролика
