[AI CC-CC2022] Редактирование скрипта для автоматического обрезания и удаления векторных объектов вне артбордов

Ant-3

Участник
Топикстартер
Сообщения
81
Реакции
2
Доброго дня!
Недавно наткнулся в интернетах на скрипт для автоматического обрезания и удаления векторных объектов вне главного артборда.
Он практически моментально справляется со своей задачей при наличии большого количества объектов, что для меня важно.

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

Скрипт "Cropulka" зависает намертво,
Скрипты "Cropper FREE" и "Super Magic Eraser" работают очень долго.


Ниже скрипт, который мне понравился, но в данном виде он работает только на один артборд. Может его можно заставить работать сразу на все артборды в документе (ну или чтобы он поэтапно проходился по каждому артборду)? Самостоятельно не понял как это сделать.
И надеюсь, что если его переделать, то он как "Cropper FREE" и "Super Magic Eraser" не станет так же медленно работать, на 4 артборда порой у этих скриптов уходит 10-15 минут.


Код:
function is_on_border(ol, or, ot, ob, h, w)
{
    var a = ((ob<0) && (ot>-h));
    var b = ((or>0) && (ol<w));
    if ((!a)||(!b))
    {
        return 2;
    }
    if (((ol < 0) && (or > 0)) || ((ol < w) && (or > w)) )
    {
        if (a)
        {
            //на границе
            return 1;
        }
        else
        {
            //за границей
            return 2;
        }
       
    }
    if (((ot > 0) && (ob < 0)) || ((ot > -h) && (ob < -h)))
    {
        if (b)
        {
            //на границе
            return 1;
        }
        else
        {
            //за границей
            return 2;
        }
    }
    return 0;
}

function process_objects(pageItems, newGroup, h, w)
{  
    var thisItem;
    for(var i = pageItems.length - 1; i > -1;  i--){
            thisItem = pageItems[i];                    
            res = is_on_border(thisItem.left, thisItem.left + thisItem.width, thisItem.top, thisItem.top - thisItem.height, h, w);
            if ((res==1)&&(thisItem!=newGroup))
            {      
                thisItem.move(newGroup, ElementPlacement.PLACEATBEGINNING);            
            }
            else if (res==2)
            {
                thisItem.remove();
            }          
        };
}

function ArtboardCrop(){
    app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
    if(app.documents.length  > 0){
        var doc = app.activeDocument;
       
        var newGroup = doc.groupItems.add();    
        h = doc.height;
        w = doc.width;

        process_objects(doc.layers[0].pageItems, newGroup, h, w);
        var activeArtboardIndex = doc.artboards.getActiveArtboardIndex();
        var rc =  doc.artboards[activeArtboardIndex].artboardRect;
        var newRect = doc.pathItems.rectangle(rc[1],rc[0],rc[2],-rc[3]);
        newRect.filled = false;
        newRect.stroked = false;
        newRect.move(newGroup, ElementPlacement.PLACEATBEGINNING);
        newGroup.selected = true;
        //app.executeMenuCommand("selectall");
       
        app.executeMenuCommand("Live Pathfinder Crop");
        app.executeMenuCommand("expandStyle");
    }
}
ArtboardCrop();
 
Последнее редактирование:
Наверное так
JavaScript:
for (var a=0; a < app.activeDocument.artboards.length; a++) {
    app.activeDocument.artboards.setActiveArtboardIndex(a);
    ArtboardCrop();
}
Но чет у меня он и на одном артборде спотыкается... :) Но если Вас устраивает, то ок :)
 
Скрипты работают долго (смотря какое железо) потому, что охватывают много вариантов объектов. Говоря о cropulka, там и предварительное сохранение и восстановление статусов всех объектов (залочен, видим — из-за этих функций в большом документе сильно замедляется), и резка растров, мешей, и т.д. У найденного тобой меньше возможностей — от того и быстрый. Первое что бросается в глаза:
1) создает группу, куда помещает все объекты — что плохо, если у пользователя объекты намеренно разложены по разным слоям.
2) Режет только простые векторные объекты (не умеет клиппинг маски, меши, растры)
Если для твоих файлов этого скрипта достаточно, то как-то так по-быстрому по всем артбордам им пройтись можно. Поменять чуть функцию обрезки и циклом, как предлагал Drawer:
JavaScript:
function artboardCrop(idx) {
    app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
    var doc = app.activeDocument;
    selection = null;
    doc.artboards.setActiveArtboardIndex(idx);
    doc.selectObjectsOnActiveArtboard();
    var newGroup = selection[0].layer.groupItems.add();
    h = doc.height;
    w = doc.width;
    process_objects(selection, newGroup, h, w);
    var rc =  doc.artboards[idx].artboardRect;
    var newRect = doc.pathItems.rectangle(rc[1],rc[0],rc[2],-rc[3]);
    newRect.filled = false;
    newRect.stroked = false;
    newRect.move(newGroup, ElementPlacement.PLACEATBEGINNING);
    newGroup.selected = true;
    
    app.executeMenuCommand("Live Pathfinder Crop");
    app.executeMenuCommand("expandStyle");
}
if (app.documents.length > 0) {
    for (var i = 0; i < app.activeDocument.artboards.length; i++) {
        artboardCrop(i);
    }
}
 
Последнее редактирование:
  • Спасибо
Реакции: Drawer
Скрипты работают долго (смотря какое железо) потому, что охватывают много вариантов объектов. Говоря о cropulka, там и предварительное сохранение и восстановление статусов всех объектов (залочен, видим — из-за этих функций в большом документе сильно замедляется), и резка растров, мешей, и т.д. У найденного тобой меньше возможностей — от того и быстрый. Первое что бросается в глаза:
1) создает группу, куда помещает все объекты — что плохо, если у пользователя объекты намеренно разложены по разным слоям.
2) Режет только простые векторные объекты (не умеет клиппинг маски, меши, растры)
Если для твоих файлов этого скрипта достаточно, то как-то так по-быстрому по всем артбордам им пройтись можно. Поменять чуть функцию обрезки и циклом, как предлагал Drawer:
JavaScript:
function artboardCrop(idx) {
    app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
    var doc = app.activeDocument;
    selection = null;
    doc.artboards.setActiveArtboardIndex(idx);
    doc.selectObjectsOnActiveArtboard();
    var newGroup = selection[0].layer.groupItems.add();
    h = doc.height;
    w = doc.width;
    process_objects(selection, newGroup, h, w);
    var rc =  doc.artboards[idx].artboardRect;
    var newRect = doc.pathItems.rectangle(rc[1],rc[0],rc[2],-rc[3]);
    newRect.filled = false;
    newRect.stroked = false;
    newRect.move(newGroup, ElementPlacement.PLACEATBEGINNING);
    newGroup.selected = true;
  
    app.executeMenuCommand("Live Pathfinder Crop");
    app.executeMenuCommand("expandStyle");
}
if (app.documents.length > 0) {
    for (var i = 0; i < app.activeDocument.artboards.length; i++) {
        artboardCrop(i);
    }
}

Привет, спасибо большое за помощь! Да, все верно, мне это нужно только для большого количества простых векторных объектов.

Этот отрывок, как я понял, нужно за место этого вставить:
Код:
function ArtboardCrop(){
    app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
    if(app.documents.length  > 0){
        var doc = app.activeDocument;
       
        var newGroup = doc.groupItems.add();    
        h = doc.height;
        w = doc.width;

        process_objects(doc.layers[0].pageItems, newGroup, h, w);
        var activeArtboardIndex = doc.artboards.getActiveArtboardIndex();
        var rc =  doc.artboards[activeArtboardIndex].artboardRect;
        var newRect = doc.pathItems.rectangle(rc[1],rc[0],rc[2],-rc[3]);
        newRect.filled = false;
        newRect.stroked = false;
        newRect.move(newGroup, ElementPlacement.PLACEATBEGINNING);
        newGroup.selected = true;
        //app.executeMenuCommand("selectall");
       
        app.executeMenuCommand("Live Pathfinder Crop");
        app.executeMenuCommand("expandStyle");
    }
}
ArtboardCrop();

Не понял только за место чего или куда именно вот это вставлять:

Код:
for (var a=0; a < app.activeDocument.artboards.length; a++) {
    app.activeDocument.artboards.setActiveArtboardIndex(a);
    ArtboardCrop();
}

Drawer кстати тоже благодарствую за помощь.
 
Последнее редактирование:
  • Спасибо
Реакции: Drawer
Какой отрывок? creold полный скрипт выложил
хм, просто он у меня с ошибкой запускается, я и подумал, что это отрывок. Вот что пишет:
Error 24: process_objects не является функцией. Line: 10
process_objects(selection, newGroup, h, w);
 
А, точно, добавьте все что выше строки
function ArtboardCrop()
 
Чтобы не путаться, тогда вот целиком скрипт
JavaScript:
function is_on_border(ol, or, ot, ob, h, w) {
  var a = ((ob < 0) && (ot > -h));
  var b = ((or > 0) && (ol < w));
  if ((!a) || (!b)) {
    return 2;
  }
  if (((ol < 0) && (or > 0)) || ((ol < w) && (or > w))) {
    if (a) {
      //на границе
      return 1;
    } else {
      //за границей
      return 2;
    }
  }
  if (((ot > 0) && (ob < 0)) || ((ot > -h) && (ob < -h))) {
    if (b) {
      //на границе
      return 1;
    } else {
      //за границей
      return 2;
    }
  }
  return 0;
}

function process_objects(pageItems, newGroup, h, w) {
  var thisItem;
  for (var i = pageItems.length - 1; i > -1; i--) {
    thisItem = pageItems[i];
    res = is_on_border(thisItem.left, thisItem.left + thisItem.width, thisItem.top, thisItem.top - thisItem.height, h, w);
    if ((res == 1) && (thisItem != newGroup)) {
      thisItem.move(newGroup, ElementPlacement.PLACEATBEGINNING);
    } else if (res == 2) {
      thisItem.remove();
    }
  };
}

function artboardCrop(idx) {
  var doc = app.activeDocument;
  selection = null;
  doc.artboards.setActiveArtboardIndex(idx);
  doc.selectObjectsOnActiveArtboard();

  var newGroup = selection[0].layer.groupItems.add();
  h = doc.height;
  w = doc.width;
  process_objects(selection, newGroup, h, w);

  var rc = doc.artboards[idx].artboardRect;
  var newRect = doc.pathItems.rectangle(rc[1], rc[0], rc[2], -rc[3]);
  newRect.filled = false;
  newRect.stroked = false;
  newRect.move(newGroup, ElementPlacement.PLACEATBEGINNING);

  newGroup.selected = true;
  app.executeMenuCommand("Live Pathfinder Crop");
  app.executeMenuCommand("expandStyle");
  if (selection[0].typename == "GroupItem" && !selection[0].pageItems.length) {
    selection[0].remove();
  }
}

if (app.documents.length > 0) {
  var docCoord = app.coordinateSystem;
  app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
  for (var i = 0; i < app.activeDocument.artboards.length; i++) {
    artboardCrop(i);
  }
  selection = null;
  app.coordinateSystem = docCoord;
}
 
Последнее редактирование:
  • Спасибо
Реакции: Drawer и ITIT
Чтобы не путаться, тогда вот целиком скрипт
JavaScript:
function is_on_border(ol, or, ot, ob, h, w) {
  var a = ((ob < 0) && (ot > -h));
  var b = ((or > 0) && (ol < w));
  if ((!a) || (!b)) {
    return 2;
  }
  if (((ol < 0) && (or > 0)) || ((ol < w) && (or > w))) {
    if (a) {
      //на границе
      return 1;
    } else {
      //за границей
      return 2;
    }
  }
  if (((ot > 0) && (ob < 0)) || ((ot > -h) && (ob < -h))) {
    if (b) {
      //на границе
      return 1;
    } else {
      //за границей
      return 2;
    }
  }
  return 0;
}

function process_objects(pageItems, newGroup, h, w) {
  var thisItem;
  for (var i = pageItems.length - 1; i > -1; i--) {
    thisItem = pageItems[i];
    res = is_on_border(thisItem.left, thisItem.left + thisItem.width, thisItem.top, thisItem.top - thisItem.height, h, w);
    if ((res == 1) && (thisItem != newGroup)) {
      thisItem.move(newGroup, ElementPlacement.PLACEATBEGINNING);
    } else if (res == 2) {
      thisItem.remove();
    }
  };
}

function artboardCrop(idx) {
  var doc = app.activeDocument;
  selection = null;
  doc.artboards.setActiveArtboardIndex(idx);
  doc.selectObjectsOnActiveArtboard();

  var newGroup = selection[0].layer.groupItems.add();
  h = doc.height;
  w = doc.width;
  process_objects(selection, newGroup, h, w);

  var rc = doc.artboards[idx].artboardRect;
  var newRect = doc.pathItems.rectangle(rc[1], rc[0], rc[2], -rc[3]);
  newRect.filled = false;
  newRect.stroked = false;
  newRect.move(newGroup, ElementPlacement.PLACEATBEGINNING);

  newGroup.selected = true;
  app.executeMenuCommand("Live Pathfinder Crop");
  app.executeMenuCommand("expandStyle");
  if (selection[0].typename == "GroupItem" && !selection[0].pageItems.length) {
    selection[0].remove();
  }
}

if (app.documents.length > 0) {
  var docCoord = app.coordinateSystem;
  app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
  for (var i = 0; i < app.activeDocument.artboards.length; i++) {
    artboardCrop(i);
  }
  selection = null;
  app.coordinateSystem = docCoord;
}
Работает вообще классно, благодарствую еще раз помощь!
 
Работает действительно классно,НО есть и ,,ложка дёгтя,,.
При повторном запуске скрипта на ,,обрезанных,, только что артбордах удаляет все обьекты оставшиеся на них.
Это мелочи жизни если быть внимательным и всегда есть Ctrl+Z
 
Понятно. Чтобы это пофиксить, надо добавить сброс селекшена со всех объектов на артборде, перед строкой которая выбирает собранную группу "newGroup" для кропа. Иначе накладывается, что в выделении может быть и новая группа, и просто какая-то старая группа объектов на этом артборде. И тогда эффект кропа ко всем группам применится, что не нужно.
JavaScript:
selection = null;
newGroup.selected = true;
 
Последнее редактирование:
  • Спасибо
Реакции: ITIT