[AI CC2022] Редактирование скрипта Envelope Distort

Ant-3

Участник
Топикстартер
Сообщения
71
Реакции
2
Доброго дня. В очередной раз в интернетах наткнулся на интересный для меня скрипт, но понимания как его немного видоизменить нет. Вот скрипт:

Код:
var sel = app.activeDocument.selection;      // all the objects that have been selected
var lowest = sel[sel.length-1];              // the lowest object

for (var i=0; i<sel.length-1; i++) {
    var top       = sel[i].duplicate();      // make a copy of the next object
    var btm       = lowest.duplicate();      // make a copy of the lowest object
    app.selection = null;                    // deselect all
    top.selected  = true;                    // select the top copy
    btm.selected  = true;                    // select the bottom copy
    app.executeMenuCommand('Make Envelope'); // make Envenlope
}


Скрипт применяет Envelope Distort ( в иллюстраторе это: Object - Envelope Distort (объект - искажение с помощью оболочки)) с нижнего объекта, на один (или несколько) верхних , если они оба выделены и не удаляет при этом нижний объект. К сожалению, после работы скрипта остается тот объект (синий квадрат на видео), на который применялся Envelope Distort.

Еще в конце не применяется функция "разобрать" (expand (разобрать) , в том же разделе Object - Envelope Distort (объект - искажение с помощью оболочки)). Это не особо важно, но удобнее конечно, когда она применятся на верхний (ие) объект (ы), чтобы сразу было видно сетку.

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

(показал на втором видео, как примерно должен работать скрипт) (на первом видео, как сейчас работает).

Заранее благодарю форумчан за помощь, не раз уже (по моим очень скромным познаниям в сфере скриптинга) очень крутые вещи творили с кодом.





 
Последнее редактирование:

creold

Сергей Осокин
Сообщения
37
Реакции
55
JavaScript:
var sel = app.activeDocument.selection;
var lowest = sel[sel.length - 1];

for (var i = sel.length - 2; i >= 0; i--) {
  var top = sel[i].duplicate();
  var btm = lowest.duplicate();
  app.selection = null;
  top.selected = true;
  btm.selected = true;
  app.executeMenuCommand('Make Envelope');
  app.executeMenuCommand('Expand Envelope');
  sel[i].remove();
}

Про артборды понятно, что не понятно. Скрипт должен уметь «умно» распознать, когда ты выделил кучу объектов, что какие из объектов принадлежат к каким артбордам? А потом скрипт должен разделить все выделенное на «кучки» по их артбордам и сделать поочередно энвелоп? Не усложняя алгоритм скрипта, проще сделать, чтобы скрипт прошелся сам по каждому артборду, выделил там все объекты и провел операцию. Но да, вдруг у тебя на артборде есть лишние объекты, которые не надо трогать.
 

Ant-3

Участник
Топикстартер
Сообщения
71
Реакции
2
Creold, привет! А может быть можно сделать так, чтобы все слои в документе, кроме выделенных мной, блокировались или скрывались, а после работы скрипта (внутри каждого артборда) все в конце разблокировалась или появлялось.
Может быть из-за версии иллюстратора, но у меня скрипт почему-то не срабатывает, только если выделить несколько объектов, то срабатывает 'Make Envelope' и 'Expand Envelope' после активации скрипта
 

Ant-3

Участник
Топикстартер
Сообщения
71
Реакции
2
извиняюсь, остальные функции в скрипте тоже работают, но только на тех объектах, которые сейчас выделены
 

Chiga

15 лет на форуме
Сообщения
827
Реакции
528
внутри каждого артборда
Для иллюстратора артборд это только 4 координаты в документе и принадлежность объекта артборду нужно вычислить, а это не
немного видоизменить
Исходный скрипт я бы поменял так
Код:
var sel = app.activeDocument.selection;
var lowest = sel[sel.length - 1];

for (var i = sel.length - 2; i >= 0; i--) {
  var top = sel[i];
  var btm = lowest.duplicate();
  app.selection = null;
  top.selected = true;
  btm.selected = true;
  app.executeMenuCommand('Make Envelope');
  app.executeMenuCommand('Expand Envelope');
  app.executeMenuCommand('ungroup');
}
app.selection = null;
Не усложняя алгоритм скрипта, проще сделать, чтобы скрипт прошелся сам по каждому артборду, выделил там все объекты
Хотелось бы посмотреть.
 
  • Спасибо
Реакции: ITIT

creold

Сергей Осокин
Сообщения
37
Реакции
55
2024-05-11 09.07.39.gif

JavaScript:
//@target illustrator
function main() {
  var isUseAll = false; // true — all artboards, false — only active

  if (documents.length === 0) return;

  var doc = app.activeDocument;
  var docAbs = doc.artboards;
  var currIdx = docAbs.getActiveArtboardIndex();
  app.executeMenuCommand('deselectall');

  if (isUseAll) {
    for (var i = 0; i < docAbs.length; i++) {
      doc.artboards.setActiveArtboardIndex(i);
      doc.selectObjectsOnActiveArtboard();
      makeEnvelope(app.selection);
    }
    // Return original active artboard
    doc.artboards.setActiveArtboardIndex(currIdx);
  } else {
    doc.selectObjectsOnActiveArtboard();
    makeEnvelope(app.selection);
  }
}

function makeEnvelope(arr) {
  if (arr.length === 0) return;
  var sel = app.activeDocument.selection;
  var lowest = sel[sel.length - 1];
 
  for (var i = sel.length - 2; i >= 0; i--) {
    var top = sel[i];
    var btm = lowest.duplicate();
    app.selection = null;
    top.selected = true;
    btm.selected = true;
    app.executeMenuCommand('Make Envelope');
    app.executeMenuCommand('Expand Envelope');
    app.executeMenuCommand('ungroup');
  }

  app.executeMenuCommand('deselectall');
}

try {
  main();
} catch (e) {}
 
  • Спасибо
Реакции: Ant-3, Chiga и ITIT

creold

Сергей Осокин
Сообщения
37
Реакции
55
лочил/разлочил все что не выделено
Если глубоко копать, то это тоже не универсальное решение. В документе может быть до этого были уже заблокированные объекты. Если скрипт сделает инверсию селекшена и заблокирует остальное, а в конце вызовет команду «unlock all», то разблокируются и объекты, которые нельзя было трогать.

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

creold

Сергей Осокин
Сообщения
37
Реакции
55
2024-05-11 10.29.52.gif

Мне такие решения не нравятся, так как не учитывают всех нюансов. Пользователь подобных скриптов должен быть уверен, что у него все макеты «простые»

JavaScript:
//@target illustrator
function main() {
  var isUseAll = true; // true — all artboards, false — only active

  if (documents.length === 0) return;

  var doc = app.activeDocument;
  var docAbs = doc.artboards;
  var currIdx = docAbs.getActiveArtboardIndex();

  app.executeMenuCommand('Inverse menu item');
  app.executeMenuCommand('lock');
  app.executeMenuCommand('deselectall');

  if (isUseAll) {
    for (var i = 0; i < docAbs.length; i++) {
      doc.artboards.setActiveArtboardIndex(i);
      doc.selectObjectsOnActiveArtboard();
      makeEnvelope(app.selection);
    }
    // Return original active artboard
    doc.artboards.setActiveArtboardIndex(currIdx);
  } else {
    doc.selectObjectsOnActiveArtboard();
    makeEnvelope(app.selection);
  }

  app.executeMenuCommand('unlockAll');
  app.executeMenuCommand('deselectall');
}

function makeEnvelope(arr) {
  if (arr.length === 0) return;
  var sel = app.activeDocument.selection;
  var lowest = sel[sel.length - 1];
 
  for (var i = sel.length - 2; i >= 0; i--) {
    var top = sel[i];
    var btm = lowest.duplicate();
    app.selection = null;
    top.selected = true;
    btm.selected = true;
    app.executeMenuCommand('Make Envelope');
    app.executeMenuCommand('Expand Envelope');
    app.executeMenuCommand('ungroup');
  }

  app.executeMenuCommand('deselectall');
}

try {
  main();
} catch (e) {}
 
  • Спасибо
Реакции: Ant-3

creold

Сергей Осокин
Сообщения
37
Реакции
55
С массивом заблокированных
JavaScript:
//@target illustrator
function main() {
  var isUseAll = true; // true — all artboards, false — only active

  if (documents.length === 0) return;

  var doc = app.activeDocument;
  var docAbs = doc.artboards;
  var currIdx = docAbs.getActiveArtboardIndex();

  app.executeMenuCommand('Inverse menu item');
  var tmpLocked = app.selection;
  app.executeMenuCommand('lock');
  app.executeMenuCommand('deselectall');

  if (isUseAll) {
    for (var i = 0; i < docAbs.length; i++) {
      doc.artboards.setActiveArtboardIndex(i);
      doc.selectObjectsOnActiveArtboard();
      makeEnvelope(app.selection);
    }
    // Return original active artboard
    doc.artboards.setActiveArtboardIndex(currIdx);
  } else {
    doc.selectObjectsOnActiveArtboard();
    makeEnvelope(app.selection);
  }

  for (var j = 0; j < tmpLocked.length; j++) {
    tmpLocked[j].locked = false;
  }
  app.executeMenuCommand('deselectall');
}

function makeEnvelope(arr) {
  if (arr.length === 0) return;
  var sel = app.activeDocument.selection;
  var lowest = sel[sel.length - 1];
 
  for (var i = sel.length - 2; i >= 0; i--) {
    var top = sel[i];
    var btm = lowest.duplicate();
    app.selection = null;
    top.selected = true;
    btm.selected = true;
    app.executeMenuCommand('Make Envelope');
    app.executeMenuCommand('Expand Envelope');
    app.executeMenuCommand('ungroup');
  }

  app.executeMenuCommand('deselectall');
}

try {
  main();
} catch (e) {}
 
  • Спасибо
Реакции: Drawer, Ant-3 и Chiga

Ant-3

Участник
Топикстартер
Сообщения
71
Реакции
2
Ребят, привет, вроде все уже работает так, как хотелось, еще чуть позже на большом массиве только перепроверю на всякий случай (и еще кое-что другое проверю). Огромные благодарствия Вам creold и Chiga !
 

Ant-3

Участник
Топикстартер
Сообщения
71
Реакции
2
где-то на 37 артборде у меня перестает работать половина функционала, срабатывает только блокирование. Если как-то это можно подправить, то будет хорошо, если нет - то и все равно. И так уже хорошо
 

Drawer

Участник
Сообщения
1 889
Реакции
834

Drawer

Участник
Сообщения
1 889
Реакции
834
Последнее редактирование:

Chiga

15 лет на форуме
Сообщения
827
Реакции
528
Вот где 2 дня ждать
Код:
function main() {
    if (documents.length === 0) return;
    if (app.activeDocument.selection.length === 0) return;
    var doc = app.activeDocument;
    var docArts = doc.artboards;
    var arts = new Array();
    for (var i = 0; i < docArts.length; i++) {
        var sel = app.activeDocument.selection;
        if (sel.length == 0) break;
        var artItems = new Array();
        var arbRect = docArts[i].artboardRect;
        for (var s = 0; s < sel.length; s++){
            if(onBoard(sel[s].geometricBounds, arbRect)){
                artItems.push(sel[s])
                sel[s].selected = false;
            }
        }
        if (artItems.length > 0) arts.push(artItems);
    }
    for (var i = 0; i < arts.length; i++) {
        for (var s = 0; s < arts[i].length; s++){
            arts[i][s].selected = true;
        }
        makeEnvelope();
    }
}
function onBoard(a, b) {
    return !(a[1] < b[3] || a[3] > b[1] || a[2] < b[0] || a[0] > b[2]);
}
function makeEnvelope() {
    var sel = app.activeDocument.selection;
    var lowest = sel[sel.length - 1];
  
    for (var i = sel.length - 2; i >= 0; i--) {
      var top = sel[i];
      var btm = lowest.duplicate();
      app.selection = null;
      top.selected = true;
      btm.selected = true;
      app.executeMenuCommand('Make Envelope');
      app.executeMenuCommand('Expand Envelope');
      app.executeMenuCommand('ungroup');
    }
      app.executeMenuCommand('deselectall');
  }
 
  try {
    main();
  } catch (e) {}

Мне так больше нравится )
 
  • Спасибо
Реакции: Drawer и Ant-3

Drawer

Участник
Сообщения
1 889
Реакции
834
Мне так больше нравится )
Ну ради бога, нравится так нравится :) Однако это не
перебирать все итемы в документе
:)
Кроме того, проверка на принадлежность артборду
Код:
function onBoard(a, b) {
    return !(a[1] < b[3] || a[3] > b[1] || a[2] < b[0] || a[0] > b[2]);
}
по geometricBounds
Сразу даст результат отличный от doc.selectObjectsOnActiveArtboard(); ну например в таком варианте с клипмаской объекта :)
Что вероятно для этого скрипта не критично надо отметить :)
1715524102405.png

И еще, то что Вы выделяете скриптом по очереди объекты из массива вместо лочить/выделить все на артборде, никак мне думается не избавляет от глюка AI "действие опережает мысль" :) Как бы не усугубляло :)
На тестовом файле из 100 артбордов скрипт Сергея без изменений отработал за 30 сек, с redraw() за 40 сек, Ваш за 31 сек, но поскольку все 3 варианта отработали без проблем и спотыканий, не могу сказать, получилось ли избавиться от "затыка" воткнув redraw() и будет ли повторяться баг на Вашем скрипте :)
 
Последнее редактирование:
  • Спасибо
Реакции: Ant-3 и Chiga