101 СПОСОБ  ЗАРАБОТАТЬ   НА ПЕЧАТИ

Скрипты под Illustrator: долой рутину!

  • 2 августа 2004 г.
  • 22404
Обычно, если речь идёт о программах для дизайнеров, первостепенное внимание уделяется художественным возможностям приложений — инструментам рисования, фильтрам и т. п. Но в повседневной жизни приходится заниматься и рутиной. К счастью, ПО от Adobe (в т. ч. Illustrator) стало поддерживать написание сценариев (скриптов), позволяющих переложить монотонный труд на плечи машины. И вы уже не работаете в Illustrator — вы им управляете, а это, как говорят в Одессе, две большие разницы!

Отдавая отчёт, что подавляющая часть пользователей Illustrator — художники и дизайнеры, не сталкивавшиеся с программированием, постараюсь построить обзор функциональности сценариев так, чтобы у читателей не сложилось впечатления, будто для этого занятия нужны какой-то «особый» склад мышления и длительное спецобразование. Одновременно приношу извинения профессионалам за некоторые упрощения в формулировках в угоду доступности материала. Сам автор когда-то был в подобной ситуации и поначалу не считал эту сферу своей епархией. Но потратил на изучение менее двух недель и теперь утверждаю: имея минимальные представления о программировании, освоить скрипты — задача вполне посильная.

Сценарии под Illustrator можно писать на любом языке: JavaScript, Visual Basic (Windows) и AppleScript (Mac OS). Поскольку с первым знакомо большинство читателей (многие дизайнеры для полиграфии успешно справляются и с созданием интернет-страниц, в которых он используется), опираться будем именно на него. К тому же JavaScript платформенно-независим: написанные на нём скрипты будут работать в обеих ОС — Windows и Mac OS. Способ обращения к элементам — объектно-ориентированный: чтобы узнать, например, толщину окантовки у второго векторного элемента на первом слое, нужно написать следующую конструкцию:

app.activeDocument.Layer[0].pathItems[1].strokeWidth

Это можно интерпретировать так: сначала указывается объект наивысшего уровня в иерархии Illustrator (app — приложение, сокращённо от application), и далее выбор постепенно сужается до конкретного элемента (в активном документе работать на первом слое; затем в указанном слое выбрать второй по глубине залегания векторный объект и узнать у него толщину окантовки). Подобный метод обращения к элементам весьма удобен, поскольку позволяет легко ориентироваться во всём многообразии их типов, существующих в редакторе. С полной моделью взаимосвязей можно познакомиться по хорошо составленному описанию (входит в комплект Illustartor).

Квадратные скобки говорят о том, что элемент — часть массива. Массив — совокупность нескольких объектов, объединённых определённым признаком. Например, Layers, pathItems, RasterItems, GroupItems, Selection и т. д. — массивы, состоящие из однотипных объектов (слоёв документа, векторных контуров, растровых изображений, групп и т. п.). В скобках указывается индекс (порядковый номер) требуемого элемента в массиве. Так, запись Layer[0] обозначает первый слой, поскольку первый индекс всегда «0».

К объектам можно обращаться и по названиям Layer[«Сhart»]. Для этого элемент нужно явно назвать — вручную, используя палитру Layers (двойной щелчок на названии объекта открывает окно с его свойствами), либо из скрипта. Чтобы не писать каждый раз громоздкую конструкцию с перечислением всей «родословной», используйте ссылки (references):

pI = activeDocument.Layer[0].pathItems;

Тогда вышеприведённый участок кода будет иметь вид: pI[1].strokeWidth.

К слою как к объекту допускается не обращаться каждый раз, если все операции происходят на одном и том же активном слое. И учтите, что в названиях переменных имеет значение регистр: если первый раз написать pI, а второй — pi, то скрипт выдаст ошибку и работать не будет.

В объектно-ориентированной модели существуют: само приложение, классы (типы объектов, или, используя более привычное понятие, существительные: слои, векторные объекты, группы и т. п.), методы (способы взаимодействия с ними — глаголы: move, duplicate и т. п.) и свойства (прилагательные: strokeWidth, fillColor, selected и т. п.). Чтобы легче ориентироваться, представьте, что приложение — это дом, в котором есть различные предметы — аналог классов (окна, двери), обладающие некоторыми свойствами (пластиковые, деревянные), с которыми выполняют определённые действия — методы (открывают, закрывают). Понимая суть подобной иерархии, гораздо проще разобраться в скриптинге.

На самом верхнем уровне находится приложение, и, буквально следуя правилу подчинённости объектов, его пришлось бы указывать при любом действии. В целях упрощения ссылку на приложение можно опускать — кроме тех случаев, когда действительно требуется узнать какие-то его свойства (например, доступные шрифты — app.fonts).

Классы Layer, Group, Text могут содержать объекты того же класса, у которых также могут иметься дочерние. Полезная возможность объектного подхода — наследование свойств. Так, все векторные контуры (pathItems) являются дочерними для более общего класса — элементов страницы (pageItems). Следовательно, назначив определённые свойства pageItems, мы автоматически назначаем его и pathItems.

Несмотря на похожесть, классы Layers и Layer всё же различны. Первый — коллекция всех слоёв в документе, второй — только какой-то определённый, соответственно отличаются их методы и свойства. К первому можно применять методы add, removeAll, а ко второму — все операции, доступные для отдельного слоя. Непосредственно к объекту обращаются как к элементу соответствующего массива — в нашем случае через Layers[1], Layers[2] и т. д.

Выделенному элементу соответствует отдельный класс — selection, который также является массивом (выделена может быть группа объектов). На особом счету в Illustrator классы pluginItems, Colors, Views. Первый имеет множество ограничений, связанных с тем, что объекты такого типа «не родные» для Illustrator. К ним относятся элементы Blend, Envelope, Mesh и аналогичные. Особенности остальных будем рассматривать по мере их использования.

Чтобы скрипт был «виден», его размещают в папке Presets•Scripts, расположенной в той, где установлено приложение. Рассматривать будем реальные примеры (это позволит сразу почувствовать полезность сценариев), а писать их под Illustrator CS, поскольку его скриптинг гибче предыдущих версий.

Пример 1: объединение объектов

Начнём с самого простого — напишем скрипт, соединяющий линиями подчинённые объекты с основным (нередкая задача при создании блок-схем, технической документации и аналогичных работах). И коснёмся таких базовых вопросов, как работа с выделенными объектами, создание новых слоёв, размещение объектов, изменение их порядка, создание и включение кривых в сложный путь (compound path).

Работа с такого рода документами предполагает широкое использование символов (symbols) — внесение изменений в них автоматически обновляет все созданные копии. Однако с такими элементами Illustrator работает не всегда корректно: бывает, что не считывает названия у объектов, являющихся копиями символов. В результате их отбор по имени невыполним. Обработка же всех элементов данного типа в текущем слое практической пользы не имеет. В итоге, я склонился в пользу альтернативного варианта, при котором сначала необходимо выделить требуемые объекты (проще всего — выбором одного символа и поиском его копий через командой Select•Same Instances), а затем выделить опорный элемент, с которым они будут соединяться.

Итак, начинаем. Для сокращения введём переменную sel, к которой будем обращаться, когда нужно провести какие-либо действия над выделенным объектом. Затем проверим, сколько элементов выделено (хотя к массиву selection также относятся и любые выделенные символы текста, проверять, что выделен не текст, не будем). Запись if (sel.length<2) означает, что мы сравниваем значение length (количество объектов класса sel) с двойкой — минимальным количеством для работы сценария. Если выделенных элементов меньше, будут выполняться действия, заключённые в первые идущие за оператором if фигурные скобки, иначе — идущие после else. При этом логично предусмотреть выдачу сообщения, чтобы сориентироваться в ситуации и понять, что нужно сделать.

sel = activeDocument.selection
if (sel.length<2) {br> alert (“Not enough objects to proceed! \nSelect at least 2 objects and the last — target object!”) }
else {

Alert — стандартная функция JavaScript, которая выводит окно с заданным текстом и кнопкой ОК. «\n» означает переход на новую строку и используется, чтобы размеры окна оставались небольшими. Текст, выводимый в окне, должен быть заключён в кавычки.

Подготовительный этап

Получим координаты центра опорного объекта. Поскольку мы условились, что он — самый верхний, его номер (индекс) — «0» (sel[0]). Для вычисления координат будем использовать такие свойства объекта, как position (положение), width и height (высота и ширина). Значения position хранятся в массиве, состоящем из пары значений — координат по оси Х и Y, соответственно. Следовательно, к каждому нужно обращаться как position[0] и position[1].

refObj_x = sel[0].position[0] + (sel[0].width/2);
refObj_y = sel[0].position[1] — (sel[0].height/2);

Мы получили координаты центра опорного объекта и присвоили их двум переменным для дальнейшего использования. Во второй строке стоит знак «—», т. к. за точку отсчёта в Illustrator принят левый нижний угол документа, а position выдаёт координаты верхнего левого угла элемента.

Поскольку при работе с документом не последнюю роль играет удобство, позаботимся, чтобы создаваемые линии были на отдельном слое — такая структурированность поможет поддерживать порядок в макете различной сложности.

Создаём новый слой — он, как и любой элемент Illustrator, создаётся методом add(), применённым к соответствующему классу объектов. В скобках можно конкретизировать параметры действия: указать объект-назначение (им может быть, например, слой или даже новый документ, а также положение в месте назначения). В отличие от большинства методов, для add дополнительных параметров не предусмотрено, поэтому для переноса на самый верхний уровень воспользуемся специальным методом — zOrder, которому в качестве параметра укажем BRINGTOFRONT (зарезервированная константа, полный список которых приведён в документации). В принципе, если в документе всего один слой, специально указывать положение нового не требуется, поскольку Illustrator всегда располагает его выше текущего. Если же соединяемые объекты расположены не на самом верхнем уровне, вторая строчка будет нужна.

newlayer = activeDocument.layers.add();
newlayer.ZOrder(ZOrderMethod.BRINGTOFRONT);

Первую строку можно прочитать так: создать новый элемент путём увеличения (add) числа объектов требуемого типа (layers) и ссылку на только что созданный элемент присвоить переменной newlayer. В начальный момент слой пуст, т. к. в него ещё ничего не помещено. Для упрощения ориентации в сложном макете дадим слою название «Connectors» (методом name) — как видите, названия методов чётко говорят о выполняемых действиях.

newlayer.name = “Connectors”;

В учебных целях создадим не разрозненные соединительные линии, а объединённые в объект типа Compound Path — для удобства редактирования. Создание такого объекта повторяет уже известную процедуру, на этот раз применённую к классу compoundPathItems:

newCompoundPath = activeDocument.compoundPathItems.add();

Поскольку в прошлом шаге мы создали новый слой, он является активным — соответственно, создаваемые объекты будут располагаться на нём, и необходимости специально указывать его (activeDocument.newlayer) нет.

Определение координат подчинённых элементов

Этот процесс объединим с выводом самих соединительных линий, поскольку их количество должно соответствовать количеству объектов. Поочередно начинаем перебирать все выделенные элементы («i++» означает приращение на единицу) и считываем их координаты. Поиск начнём не с самого первого объекта из массива Selection (как вы помните, им выступает опорный объект), а со второго (sel[1]). Следующие строки нам уже знакомы:

for( i=1; i < sel.length; i++ ) {
obj_x= sel[i].position[0] + sel[i].width
obj_y = sel[i].position[1] — sel[i].height

Получив координаты центра дочернего элемента, приступим к созданию линии, соединяющей его с опорным. Для каждого выделенного элемента создаём новый объект — векторный контур, входящий в класс CompoundPath, увеличивая общее количество контуров:

newPath = newCompoundPath.pathItems.add();

Для задания простых контуров в Illustrator существует метод setEntirePath, параметрами которого выступает массив из координат начальной и конечной точек — которые, как мы уже знаем, в свою очередь задаются в виде массивов из двух значений (положения по двум осям). Наконец, заканчиваем введённое в самом начале условие «если что-то выделено».

newPath.setEntirePath( Array( Array(refObj_x, refObj_y), Array(obj_x, obj_y) ) ); }

Скрипт готов. Как видите, ничего сложного в нём нет: названия методов раскрывают их сущность, а объектно-ориентированная модель помогает чётко понимать иерархию объектов Illustrator. Особой практической ценности скрипт не представляет (он скорее обучающий), но на его примере были рассмотрены многие базовые понятия, на которые мы будем опираться в дальнейшем (работа с выделенными объектами, принцип их нумерации в массиве selection, определение координат, создание новых слоёв, вывод линий).

Пример 2: обнаружение слишком тонких контуров

Операции масштабирования в векторной графике применяются очень активно. Поэтому при уменьшении размеров объектов с тонкими линиями (если включён параметр Scale strokes) часто толщина их обводки становится ниже 0,25 pt (значения, после которого линии становятся слабо заметными) и оказывается причиной пропадания их при распечатке на струйном принтере. Встроенных в Illustrator функций поиска объектов со значениями обводки, меньше заданной, не предусмотрено. Вручную же найти их очень трудно — придётся выделять каждый объект в отдельности, что быстро отобьёт желание заниматься подобными проверками. Существенно упростит операцию скрипт.

Сам по себе сценарий в простейшем варианте небольшой, но мы зададимся целью сделать его более универсальным — расширим функциональность за счёт возможности указывать минимальную толщину в окне диалога. Конечно, можно в самом скрипте жёстко прописать эту величину и при необходимости каждый раз её корректировать, но, согласитесь, это неудобно. Также предусмотрим указание выделенного элемента как объекта-эталона с минимально допустимым значением окантовки. Параллельно для статистики подсчитаем количество элементов с изменённой толщиной и для наглядности их выделим.

Весь скрипт делится на две части: начальную (считывание значения из окна диалога или же у выделенного элемента) и заключительную (поиск среди всех объектов в документе и переназначение толщины окантовки). Кроме демонстрации доступа к объектам Illustrator, мы рассмотрим создание мини-интерфейса для ввода пользовательских значений.

Ввод значений

Первые две строки будут идентичны предыдущему примеру за исключением того, что вместо «2» станет фигурировать «0», поскольку перед работой скрипта нам нужно определить, есть ли выделенные объекты. Сравнение задаётся двойным знаком равенства (единичный присваивает значение).

var mySel = app.activeDocument.selection;
var go = true;
if (sel == 0) {

Если ничего не выделено, минимальная толщина будет задаваться через окно диалога. Выведем его при помощи стандартной функции JavaScript — prompt. Она открывает окно с полем, в которое можно ввести значение и в дальнейшем его использовать. Синтаксис функции таков: сначала идёт текст-подсказка, который будет выводиться в окне (с учётом унификации работы скрипта не будем использовать кириллицу, поскольку она часто отображается некорректно), затем следует значение, которое будет по умолчанию стоять в поле ввода. Плюса целых два: возможность сразу задать минимально допустимую толщину и указать любое значение. Создав переменную, которой присвоено значение функции prompt, можно потом использовать его в своих целях.

Забегая вперёд, замечу, что Illustrator даёт полный доступ не ко всем типам объектов — некоторые остаются за бортом. Поэтому предусмотрим визуализацию не только исправленных элементов, но и недоступных скрипту, чтобы не искать их вручную — ведь в них также могут быть проблемные объекты. Чтобы не выводить два окна диалога (для значения толщины и определения, какие элементы выделять), воспользуемся возможностями JavaScript по обработке строк. Дело в том, что содержимое заполненного пользователем поля является «строкой» (блоком информации), в которой может находиться сколько угодно параметров (через разделители). Зная разделитель, значения отдельных параметров можно легко извлечь из строки.

Соответственно, текст-подсказка окна диалога будет таким: задание минимальной толщины окантовки и условное число: «1», если нужно, чтобы скрипт выделил исправленные элементы, «2» — те, к которым «достучаться» не удалось.

value = prompt (“Specify the stroke width threshold (in pt),\n What to select: corrected objects (1) or inaccessible (2)”, “0.25, 1”)

Изначально в поле установим 0,25 пункта (единицы измерения в Illustrator по умолчанию), но при его изменении будет использоваться новое значение, и «1». «2» нужно указывать, только если скрипт найдёт недоступные объекты (мы позаботимся, чтобы он в конце работы сигнализировал об этом). И они станут выделенными, что избавит нас от ручного поиска (как известно, встроенный поиск Illustrator оставляет желать).

Со считыванием значений из пользовательского поля разобрались, переходим к их обработке. Проверим, действительно ли поле не пустое (знак «!» обозначает отрицание, т. е. «!=» эквивалентно «не равно», null — зарегистрированное слово для пустого значения). Если в нём что-то есть, строку разбиваем на отдельные блоки при помощи функции JavaScript split (в качестве разделителя определим комбинацию из символов «,») и полученные значения заносим в массив splitString. После этого значениям из массива дадим описательные названия (первое будет определять толщину, второе — режим работы).

if (value != null) {
splitString = value.split(“, “);
weight = splitString[0];
type = splitString[1]; }

Если же в пользовательском поле ничего нет — останавливаем выполнение сценария. Последняя закрывающая скобка — признак завершения условия, которое мы поставили вначале («если в документе ничего не выделено»).

else { go = false }

Если опорный объект специально выделен

Теперь напишем последовательность действий, если мы намеренно выделили элемент, чью толщину окантовки хотим использовать в качестве порогового значения. Выведем предупреждение о дальнейших действиях скрипта с помощью стандартной функции confirm (создаёт окно диалога с двумя кнопками — и ). Если нажать <Сancel>, работа прекращается, если же согласиться, скрипт продолжит работу.

else { selectedMsg = confirm (“Stroke width of selected object will be used as threshold”)
if (selectedMsg != true) {
go = false;
} else {

Переходим к основной части сценария. Сознательно не рассматриваем ситуацию, когда выделены несколько объектов, — ведь для задания толщины окантовки достаточно выбрать лишь один. Да и какое значение использовать, если оно у элементов окажется разным? Как мы уже знаем, единственно выделенный объект будет иметь индекс «0», а для получения толщины окантовки у Illustrator существует свойство strokeWidth. Учтём, что в принципе, selection может содержать не только отдельные элементы, но и часть текста (например, выделенную случайно), что не входит в наши планы, поэтому перед началом работы проверим возможностями JavaScript тип выделенного элемента на принадлежность именно массиву:

if (sel[0] isArray) {
weight = sel[0].strokeWidth;

Поскольку мы условились выделять только изменённые объекты, с самого опорного выделение нужно снять (обращаемся к его свойству selected):

sel[0].selected = false; } } }

Теперь мы полностью готовы к выполнению основной задачи сценария — поиска объектов: значение, которое будет использоваться в качестве минимально допустимой толщины, хранится в переменной wei.

Обстоятельства

Сравним его с аналогичным свойством у всех объектов в документе. Можно сразу перейти к поиску, но использование скрипта в повседневной работе потребовало учёта дополнительных обстоятельств — в макетах часто бывают как заблокированные слои, так и отдельные объекты. Следовательно, хоть в них поиск и работает, но вносить изменения нельзя. Чтобы обеспечить тотальную проверку, добавим в скрипт несколько операций: проверяя элементы на соответствие заданному критерию, одновременно разблокируем их, если это необходимо, и запомним индекс, чтобы после завершения проверки вернуть их в прежнее состояние. Вводим две переменные: первую для сокращённого доступа ко всем слоям в документе, а при помощи второй получим доступ только к заблокированным. Хранить порядковые номера последних будем в массиве, который создадим функцией JavaScript — new Array().

var dL = activeDocument.layers;
var blokedLayers = new Array();

Затем просмотрим все слои и у заблокированных (свойство locked=true) порядковый номер занесём в массив blokedLayers (при помощи функции push из JavaScript), после чего разрешим их редактирование (locked=false).

if (go == true) {
for (i=0; i
if (dL[i].locked == true) {
blokedLayers.push(i);
dL[i].locked = false;Раньше мы условились исправленные объекты выделять, но после завершения работы скрипта на заблокированных слоях этого сделать не сможем — нужно вывести соответствующее предупреждение. Для этого используем признак lockedPresence, который установим, если хотя бы один слой заблокирован.

lockedPresence = true;

То же повторим и с отдельными заблокированными элементами. В простейшем случае достаточно проверить все векторные элементы (класс pathItems), в которые как подкласс входят compound pathes, — чтобы ничто не ускользнуло от всевидящего глаза скрипта.

Подводные камни

Кроме рассмотренной ситуации с заблокированностью, существует ещё один «подводный камень». Как уже отмечалось, некоторые элементы (в частности, Blend Group и Envelope) не являются «родными» для Illustrator, они принадлежат специальному типу рluginItem. При этом доступ к таким объектам в Illustrator не предусмотрен, они — «вещь в себе». «Достучаться» до них можно только через класс более высокого уровня — pageItems, через который мы сможем хотя бы определить их присутствие и вывести в конце соответствующее предупреждение. Оно будет говорить, что, запустив скрипт ещё раз и указав в качестве второго параметра в поле ввода «2», он выделит эти «черные ящики».

pgI = activeDocument.pageItems;

Для хранения индексов заблокированных объектов создадим массив blokedPathes, а для подсчёта количества изменённых введём переменную corrected.

bloсkedPathes = new Array();
corrected = 0;

Для всех объектов выполним проверку на принадлежность типу PluginItem (свойство typename): если таковые присутствуют, установим признак pluginItemExist (его состояние будет определять вывод предупреждения о наличии таких элементов). В случае же повторной проверки (когда второй параметр в поле ввода равен «2») будем их выделять:

for( i=0; i < pgI.length; i++ ) {
if (pgI[i].typename==“PluginItem”) {
pluginItemExist = true
if (type ==“2”) { pgI[i].selected = true }

Итак, все (или практически все) возможные ситуации, возникающие в работе, мы предусмотрели и определили для них действия.

Основная проверка

Теперь настал черёд собственно проверки макета на соответствие заданному критерию окантовки. Учтём, что среди объектов могут попасться и такие, у которых окантовки нет вообще (определяется состоянием признака stroked) — следовательно, их нужно исключить из проверки.

if( ( pgI[i].strokeWidth < weight )&&( pgI[i].stroked ) ) {
if (pgI[i].locked == true) {
blokedPathes.push(i);
pgI[i].locked = false;

Этот фрагмент кода можно интерпретировать так: определяем у каждого элемента наличие окантовки и её толщину. Если она меньше минимальной (if(pI[i].strokeWidth < weight), и объект заблокирован, его индекс занести в специально созданный для такой цели массив blokedPathes, после чего разблокировать для внесения возможных изменений. Знак && обозначает логическое «И» (обязательное совпадение двух условий) — толщины меньше минимальной и присутствия окантовки.

Затем фиксируем наличие заблокированных объектов (устанавливаем признак lockedPresence для вывода в будущем предупреждения о том, что не все изменённые могут быть выделены) и сам исправленный выделяем, а его окантовке присваиваем пороговое значение — и так для всех элементов. Для статистики параллельно будем подсчитывать количество изменённых объектов.

lockedPresence = true;
pgI[i].selected = true;
pgI[i].strokeWidth = weight;
corrected++;

Ранее были рассмотрены действия для выделения непроверенных элементов (type =«2»). Теперь определим, что должно происходить в стандартной ситуации — при обычном поиске потенциально проблемных объектов.

if (type =“1”) { pgI[i].selected = true }

Восстановление статуса заблокированных элементов

Главную задачу мы выполнили — проблемные объекты исправлены и выделены. Осталось восстановить status quo — всё первоначально заблокированное вернуть в прежнее состояние. Для этого в текущем цикле считываем содержимое массива, где хранятся индексы заблокированных объектов, и каждому соответствующему элементу устанавливаем признак locked = true (метод shift выводит из массива последнее занесённое в него значение). Поскольку общее количество объектов больше заблокированных, нужно позаботиться, чтобы после опустошения массива цикл проверки заканчивался.

if (blokedPathes.length >0) {
retrievedPathes = blokedPathes.shift();
pI[retrievedPathes].locked = true;} }

Затем аналогичные действия предпримем в отношении слоёв:

for (i=0; i if (blokedLayers.length >0) {
retrieved = blokedLayers.shift();
dL[retrieved].locked = true; } }Вообще-то, для однотипных операций гораздо удобнее пользоваться функциями. Их преимущество в том, что единожды описав определённые действия, можно повторять их в полном объёме, просто вызывая в нужных местах функцию; так достигается компактность и читабельность сценария. Для повышения гибкости функции передают используемые в ней значения (параметры). Если же не хотите использовать функции, пропустите следующие два абзаца.

Составим две функции: первую — для разблокировки слоёв и объектов, вторую — для восстановления их атрибутов. Меняться в них будут только типы объектов (класс Layers и pageItems) и массивы для записи интересующих нас элементов (blokedLayers и blokedPathes) — они-то и будут фигурировать в качестве параметров функции. Первую запишем так:

function unlock(array, itemType)
if (itemType[i].locked == true) {
array.push(i);
itemType[i].locked = false;
locked = false;
}

Вместо array будем подставлять массив, вместо itemType — необходимый класс. Тогда получим два вызова — unlock (blockedLayers, dL) и unlock (blokedPathes, pgI). Аналогично запишем функцию для восстановления статуса:

function restore (array, itemType)
if (array.length > 0) {
retrieved = array.shift();
itemType[retrieved].locked = true;
}

Вывод информации о результатах проверки

Это последний этап работы скрипта. Сначала определим условие вывода сообщения, если выбран поиск нередактируемых объектов, затем условие появления предупреждения о том, что такие объекты были обнаружены:

if (type == “2”) { b = “\nCheck selected!” }
if (pluginItemExist == true) {
alert ( “Due to scripting restrictions some objects can't be affected” + b ) }

Логика выдачи предостережения о том, что не все исправленные могут быть выделены, такова:

if ( (lockedPresence == true ) && (pluginItemExist == false) ) {
warning= “\nBecause some of them are locked they can't be showed as selected” }

После чего выводим окончательные результаты:

alert ( “Number of corrected objects are: “ + corrected + warning)

Вот, собственно, и весь скрипт. Как видите, эти несколько строчек выполняют колоссальный объём работы, на которую вручную вряд ли кто-то отважится. Сценарий же выполняется моментально (в масштабных проектах, при количестве элементов порядка нескольких тысяч, начинает сказываться производительность процессора). От вас требуется только выбрать его из списка имеющихся (можно даже этого не делать — Illustrator позволяет скриптам назначать «горячие клавиши») командой Edit•Keyboard shortcuts•Menu commands•Scripts. Но учтите: названия скриптов сортируются в алфавитном порядке, поэтому добавление новых или удаление старых может привести к переназначению клавиш соседним сценариям. Вывод: после изменений в папке Presets\Scripts проверяйте соответствие клавиш.

Мы постарались сделать скрипт универсальным, что сказалось на его объёме. В самом же примитивном варианте (без учёта описанных выше особенностей и подводных камней) он занимает буквально пару строчек:

minWidth = activeDocument.selection[0].strokeWidth;
pI = activeDocument.pathItems;
for ( i=0; i < pI.length; i++ ) {
if( ( pI[i].strokeWidth < minWidth) && ( pI[i].stroked ) ) {
pI[i].strokeWidth = minWidth;
}}

А десерт?

Следующий выпуск мы посвятим визиткам: напишем скрипт, автоматизирующий их раскладку на листе. Впрочем, он пригодится и для более широкого круга задач, поскольку не имеет привязки к размерам объектов. Как и положено, предусмотрим создание выпусков во избежание проблем при неточной порезке листа, а также поворот визиток (если их верх и низ существенно отличаются). Параллельно затронем вопрос поиска объектов, цветовая модель которых отличается от заданной, что тоже не редкость при подобных работах.

ПОХОЖИЕ СТАТЬИ
Тире без отступа

Году в 2008-м в комментариях тогда ещё «Живого журнала» случился прелюбопытнейший спор об оформлении абзацного отступа: ведь правый край текстового фрейма даже при множестве переносов и с отключённой оптической компенсацией всегда выглядит сносно, а вот левый по умолчанию страдает — от красных строк и реплик; как с этим быть?

RGB-workflow в печати: почему «цифра», а не традиционный офсет

У дизайнеров есть мечта: получать в печати на бумаге нечто близкое по насыщенности к RGB-охватам, нежели тот маленький цветовой охват, что традиционно позволяют получить печатные краски европейской, да и любой другой триады CMYK.

Иллюстрируем мобильно

Приложения векторной графики для графического планшета Apple iPad почти готовы стать настоящими рабочими инструментами для профессионалов, ценящих мобильность. Предлагаем вам первую часть обзора таких приложений.

Допечатные эксцессы или 6 «детских» ошибок

Рейтинг самых частых ошибок в макетах печатной продукции по опыту типографии FastPrint, принимающей заказы через автоматизированную систему онлайн-проверки.

Лак и фольгирование со скоростью «цифры»

Подготовка макетов для цифрового облагораживания: выборочного УФ-лакирования и фольгирования.



Новый номер

Тема номера: Больше порядка. R-SUPERLAM AF-540. Пятикнижие конструкторов-полиграфистов. ARK-JET SOL 1804. Офсет – при своих. Когда ты – вне конкуренции. Бум в этикетке и не только. Глобальный плакат. Скрепка 2024. Интерлакокраска-2024. Инлегмаш 2024.



Организовав печать по текстильным материалам, стоит ли заводить своё швейное производство или лучше печатать на сторону?
    Проголосовало: 28