[AI CC-CC2022] Изменение размера Clipping Group

  • Автор темы Автор темы angelp
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

angelp

Участник
Топикстартер
Сообщения
50
Реакции
4
Необходимо для команды height или width сделать так, чтобы она действовала на видимые границы, а не геометрические.

Если проще то есть узор под обтравочной маской, его нужно изменить в размерах пропорционально на заданное число пикселей (поинтов), команда resize в принципе меняет, но делает это в процентах. Проблема в том, что бы рассчитать проценты при масштабировании, то я пользуюсь именно height или width, а они выдают геометрические размеры (ну или как они там называются), а не visibleBounds.

Ниже код того как у меня это реализовано, но повторюсь нужны visibleBounds, а как работать с ними я не разобрался, ну или если есть другой способ трансформации?

var scaleX=720*100/newGroup.height;
newGroup.resize(scaleX,100);
newGroup.height=720;

Всем кто откликнется, заранее благодарю!
 
Пока для себя придумал только такое решение, хотя для моих целей вроде как рабочее)

doc = app.activeDocument;
selectedItems=app.activeDocument.selection;
transSample = selectedItems[0].pathItems[0];

scale=720*100/transSample.height;
selectedItems[0].resize(scale,scale);
 
@angelp, для вычисления границ с учётом маски я пользуюсь такой функцией:
Код:
/**
* ai.jsx (c)MaratShagiev m_js@bk.ru 21.05.2016
*/

// for example:
alert (getBoundsExtend (selection[0]));

/**
* get item bounds, width and height
*
* @param {PageItem} item - object of Illustrator PageItem class
* @return {Array} bounds [ [ left, top, right, bottom ], width, height ]
*/
function getBoundsExtend (item) {
  if (arguments.length == 0) return false;
  try {
    if (item.typename == undefined) return false;
  } catch (e) {
    return false;
  }

  var bounds = _getBounds (item, []),
      width  = _calcElemWidthByBounds (bounds),
      height = _calcElemHeightByBounds (bounds),
      result = [bounds, width, height];

  return result;

  /**
   * LIB
   * */

  /**
   * recursive search of maximal bounds
   * @param {PageItem} item - object of Illustrator PageItem class
   * @param {Array} bounds - [ left, top, right, bottom ] (ampty array on start)
   * */
  function _getBounds (item, bounds) {
    var clipGroupElems, i, j;

    if (item.typename != 'GroupItem') { // any single container element
      return item.geometricBounds;
    }
    if (item.clipped) { // group with mask => search the mask
      clipGroupElems = item.pathItems;

      for (i = 0; i < clipGroupElems.length; i++) {
        if (clipGroupElems[i].clipping) {
          if (bounds == '') {
            bounds = clipGroupElems[i].geometricBounds;
            continue;
          }
          bounds = _compareBounds (clipGroupElems[i], bounds);
        }
      }
      return bounds;
    }

    // group without mask => detour of group elements
    for (j = 0; j < item.pageItems.length; j++) {

      var el = item.pageItems [j];

      if (el.typename != 'GroupItem') { // some pageItem exept group
        if (bounds == '') {
          bounds = el.geometricBounds;
          continue;
        }
        bounds = _compareBounds (el, bounds);
      }

      if (el.typename == 'GroupItem' && el.clipped) { // group with mask => search the mask
        clipGroupElems = el.pathItems;
        for (i = 0; i < clipGroupElems.length; i++) {
          if (clipGroupElems[i].clipping) {
            if (bounds == '') {
              bounds = clipGroupElems[i].geometricBounds;
              continue;
            }
            bounds = _compareBounds (clipGroupElems[i], bounds);
          }
        }
        continue;
      }

      if (el.typename == 'GroupItem' && !el.groupItems && !el.clipped) { // group without mask and without child groups
        if (bounds == '') {
          bounds = el.geometricBounds;
          continue;
        }
        bounds = _compareBounds (el.geometricBounds, bounds);
        continue;
      }

      if (el.typename == 'GroupItem' && el.groupItems) { // group without mask but contains groups => recursion
        for (var l = 0; l < el.pageItems.length; l++) {
          bounds = getBounds (el.pageItems[l], bounds);
        }
        continue;
      }
    }
    return bounds;

    /**
     * @param{PageItem} item - some object of the Illustrator PageItem class
     * @param{Array} boundsToCompare - [ left, top, right, bottom ]
     * @return{Array} result - the biggest bounds
     * */
    function _compareBounds (item, boundsToCompare) {
      var elemBounds = item.geometricBounds,
          result     = [];
      elemBounds[0] < boundsToCompare[0] ? result.push (elemBounds[0]) : result.push (boundsToCompare[0]);
      elemBounds[1] > boundsToCompare[1] ? result.push (elemBounds[1]) : result.push (boundsToCompare[1]);
      elemBounds[2] > boundsToCompare[2] ? result.push (elemBounds[2]) : result.push (boundsToCompare[2]);
      elemBounds[3] < boundsToCompare[3] ? result.push (elemBounds[3]) : result.push (boundsToCompare[3]);
      return result;
    }
  }

// calculate item width by it left and right bounds
  function _calcElemWidthByBounds (bounds) {
    var elemWidth = 0,
        left      = bounds[0],
        right     = bounds[2];

    (left <= 0 && right <= 0) || (left >= 0 && right >= 0) ? elemWidth = Math.abs (left - right) : '';
    left <= 0 && right >= 0 ? elemWidth = Math.abs (left) + right : '';

    return elemWidth;
  }

// calculate item height by it top and bottom bounds
  function _calcElemHeightByBounds (bounds) {
    var elemHeight = 0,
        top        = bounds[1],
        bottom     = bounds[3];

    (top <= 0 && bottom <= 0) || (top >= 0 && bottom >= 0) ? elemHeight = Math.abs (top - bottom) : '';
    top >= 0 && bottom <= 0 ? elemHeight = top + Math.abs (bottom) : '';
    return elemHeight;
  }

}
которая возвращает массив вида [ [ left, top, right, bottom ], width, height ] для объекта PageItem, переданного в функцию в качестве параметра
 
Последнее редактирование:

Не по теме:
какой индусский код )

elemBounds[0] < boundsToCompare[0] ? result.push (elemBounds[0]) : result.push (boundsToCompare[0]);
elemBounds[1] > boundsToCompare[1] ? result.push (elemBounds[1]) : result.push (boundsToCompare[1]);
elemBounds[2] > boundsToCompare[2] ? result.push (elemBounds[2]) : result.push (boundsToCompare[2]);
elemBounds[3] < boundsToCompare[3] ? result.push (elemBounds[3]) : result.push (boundsToCompare[3]);

я бы так написал

return [
Math.min(elemBounds[0], boundsToCompare[0]),
Math.max(elemBounds[1],boundsToCompare[1]),
Math.max(elemBounds[2],boundsToCompare[2]),
Math.min(elemBounds[3],boundsToCompare[3])
]

 
  • Спасибо
Реакции: dumbm1
Спасибо за помощь! Но правда для меня слишком пока громоздкий код, хотя конечно более универсален чем мое решение, но если кому-то интересно, вот более компактное решение центровке в дополнение к первоначальному по масштабированию (здесь частично использовал код, любезно предоставленный
dumbm1
))
Делался для простых переводов векторов в размеры для загрузки на CreativeMarket.

activeDocument.selectObjectsOnActiveArtboard();
selectedItems=app.activeDocument.selection;

if ( selectedItems.length == 1 && selectedItems[0].clipped == true) {

transSample = selectedItems[0].pathItems[0];

scale=720*100/transSample.height;
selectedItems[0].resize(scale,scale);

// Задаем размеры арборда для CM (1160,772)
newPath = app.activeDocument.pathItems.add();
newPath.setEntirePath (Array ([-80,14], [-80,786], [1080,786], [1080,14]));
newPath.closed = true;
newPath.selected = true;
doc.fitArtboardToSelectedArt(0);
activeDocument.selectObjectsOnActiveArtboard();


var shiftHorizontal = (newPath.width - transSample.width ) / 2;
var shiftVertical = (newPath.height - transSample.height) / 2;

*// selectedItems[0].left - transSample.left; разница в геометрической и видимой позиции

selectedItems[0].left = newPath.left + shiftHorizontal+selectedItems[0].left - transSample.left;
selectedItems[0].top = newPath.top - shiftVertical + selectedItems[0].top - transSample.top;

newPath.remove();
}
 
Статус
Закрыто для дальнейших ответов.