ExtendScript: Работа со слоями

от автора

<= Предыдущая статья ExtendScript + Expression

И так, у нас готов макет для титров. Мы движемся к финишной прямой. Нам осталось только дописать скрипт, дополнив его методами копирования моделей на сцену. 

Заходим в метод createTitres и сразу после добавления сцены запускаем цикл, проходясь по массиву с данными титров.

function createTitres(data) {    var scenesData = getScenesData();     for(var i = 0; i < scenesData.length; i++) {        var scene = getScene(scenesData[i]);         for (var j = 0; j < data.length; j++) {            var titreName = 'titre-' + j + '-' + scenesData[i].type;            var layer = scene.layers.byName(titreName);        }    } }

В цикле мы первым делом пытаемся обнаружить титр на сцене. Для этого мы обращаемся к свойству композиции layers и его методу byName. Зачем мы это делаем, обсудим чуть позже. Пока давайте рассмотрим ситуацию, когда метод возвращает нам null, что значит, нет слоя с таким именем.

if (!layer) {       var modelName = 'ModelTitre_' + data[j].type + '_' + scenesData[i].type;       var item = getTitreComp(modelName);    }  //………………………………………………………………………………………//  function getTitreComp(modelName) {    var item = getItem(modelName, CompItem);     if (!item) {        alert('Отсутствует модель ' + modelName);        return null;    }     return item.duplicate(); }

В методе getTitreComp мы находим модельку титра и, если такой не нашли, возвращаем null. Если же модель нашлась, возвращаем ее дубликат. Далее, мы переименовываем дубликат и добавляем его на сцену методом layers.add, который возвращает нам слой с дубликатом

if (item) {    item.name = titreName;    layer = scene.layers.add(item); }

Переходим к редактированию слоя. Для этого создадим метод editLayer, в который будем передавать сам слой, конечную точку предыдущего титра (она послужит стартовой для текущего) и мастер слой из композиции ModelScene, по которому мы будем проводить настройки

Чтобы получить конечную точку, мы перед запуском цикла с данными титров создадим переменную startTime равную нулю, первый титр начинается в точке ноль

var scene = getScene(scenesData[i]); var startTime = 0;

А метод editLayer будет нам возвращать новое его значение

Чтобы получить мастер слой, в методе getScenesData дополним объект сцены еще одним полем, layers, со слоями нашего макета.

data.push({    type: item.name.split('_')[1],    width: item.width,    height: item.height,    frameRate: Math.floor(1 / item.frameDuration),    duration: item.duration,    layers: item.layers });

А в методе createTitres получим из этого поля интересующий нас слой. И передадим все это методу editLayer

if (item) {    item.name = titreName;    layer = scene.layers.add(item);    var modelLayer = scenesData[i].layers.byName(modelName);    startTime = editLayer(layer, startTime, modelLayer); }

Теперь давайте создадим метод editLayer

function editLayer(layer, startTime, modelLayer) {    if (modelLayer) {        // Настройки по мастер-слою    } else {       // Настройки по умолчанию    } }

В нем мы проверяем, есть ли мастер-слой и если его нет, делаем все настройки по умолчанию. Давайте с дефолтных и начнем, так как их меньше.

layer.startTime = startTime; layer.outPoint = startTime + 5;

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

Настроек по мастер слою будет на одну больше,

layer.label = modelLayer.label; layer.startTime = startTime; var layerDuration = modelLayer.outPoint - modelLayer.startTime; layer.outPoint = startTime + layerDuration;

Первой строкой мы назначаем слою цвет, в который он будет покрашен на таймлайне. Это очень удобно, когда у вас несколько разных типов титров. Далее, как и в дефолтных, настройках указываем точку входа слоя. Третьей строкой мы высчитываем продолжительность слоя в мастере и прибавив это значение к startTime, получаем значение layer.outPoint, которое и возвращаем в итоге. 

Финальный вид этот метод имеет следующий

function editLayer(layer, startTime, modelLayer) {    layer.startTime = startTime;     if (modelLayer) {        layer.label = modelLayer.label;        var layerDuration = modelLayer.outPoint - modelLayer.startTime;        layer.outPoint = startTime + layerDuration;    } else {        layer.outPoint = startTime + 5;    }     return layer.outPoint; }

Снова возвращаемся в метод createTitres. Теперь нам надо отредактировать Expressions в наших титрах. Если помните из прошлой статьи, мы в выражениях ссылались на ModelScene_1x1. Теперь же нам надо заменить эти ссылки на на нашу композицию scene-1×1

startTime = editLayer(layer, startTime, modelLayer); changeExpression(    item,    'ModelScene_' + scenesData[i].type,    'scene-' + scenesData[i].type );  //................................................................  function changeExpression(comp, search, replacement) {    for (var i = 1; i <= comp.numLayers; i++) {        var layer = comp.layer(i);        var propGroup = layer.property('ADBE Transform Group');         for (var j = 1; j <= propGroup.numProperties; j++) {            var prop = propGroup.property(j);            if (prop.expression) {                prop.expression = prop.expression.replace(                    new RegExp(search, 'g'),                    replacement                )            }        }    } }

Метод changeExpression получает композицию с титром, строку которую следует заменить и строку на которую меняем. В самом методе мы проходимся по всем слоям композиции. Количество слоев хранит свойство композиции numLayers. Индексация слоев начинается с единицы. Находим группу свойств слоя ADBE Transform Group (с наименованиями объектов в After Effects можете ознакомиться  тут).  Проходим по всем свойствам группы, их количество хранит numProperties. А далее, находим свойство содержащее выражение и заменяем все вхождения ModelScene_1x1 на titre-1×1.

Анимация уже работает. Последнее, что нам осталось сделать, это поменять текст в титре.

changeExpression(    item,    'ModelScene_' + scenesData[i].type,    'scene-' + scenesData[i].type ); setText(item.layers.byName('reference_text'), data[j].text)  //................................................................  function setText(layer, text) {    if (layer) {       var property = layer.text.property("Source Text");       var value = property.value;       value.text = text;       property.setValue(value);    } }

Мы передаем методу setText слой reference_text, о котором заранее договорились содержать его в каждом макете титра, а также сам текст.

Метод setText обращается к свойству текстового слоя SourceText, меняет в его значение свойство text, вновь передавая значение свойству, не пропустите это последнее действие, иначе свойство не поменяет значение.

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

for (var j = 0; j < data.length; j++) {    var titreName = 'titre-' + j + '-' + scenesData[i].type;    var layer = scene.layers.byName(titreName);     if (!layer) {        var modelName = //....        //....    } else {        setText(            layer.source.layers.byName('reference_text'),            data[j].text        );    } }

Мы лишь меняем текст в титре. Для этого мы обращаемся к свойству слоя source, хранящее композицию, из которой состоит сам слой.

Скрипт готов. Можем его проверить. Вставляем текст титров в текстовое окно плагина

#simple Текст первого титра Тип данного титра simple  #simple Титры simple могут быть и в одну строку  #double Текст третьего титра Тип этого титра double

Титры выстроились на сцене.

Можем выставить их в нужное место таймлайна, изменить длительность. 

Второй титр не умещается в рамках сцены.

Можно исправление внести в окне плагина и вновь запустив скрипт, можно зайти в композицию титра и отредактировать слой refernce_text.

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

Скрипт с комментариями вы можете найти тут

Документацию по работе со слоями в ExtendScript тут.

Спасибо за внимание. Если эти уроки окажутся кому-то полезны, будет приятно  узнать о проектах, в которых читатели применят данные навыки.

<= Предыдущая статья ExtendScript + Expression

ссылка на оригинал статьи https://habr.com/ru/post/545704/


Комментарии

Добавить комментарий

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