Giter VIP home page Giter VIP logo

Comments (5)

creold avatar creold commented on May 14, 2024 1

@futuremotiondev Yes, it has to do with the Adobe Illustrator Prefs file, the value of the rulers in it, and the artboard rulers in the file if the file was saved with previous Adobe Illustrator Prefs settings.

You can test this small fix for both scripts in the zip archive.
FitSelectionToArtboards.zip

from illustrator-scripts.

futuremotiondev avatar futuremotiondev commented on May 14, 2024

That did the trick! Thank you so much for making the modification and also for the lightning fast turnaround. You are an Illustrator scripting god!

Best,
Jay

from illustrator-scripts.

futuremotiondev avatar futuremotiondev commented on May 14, 2024

One more thing - do you happen to have a one-click script like FitSelectionToArtboards that doesn't have a dialog box and always defaults to "Visible" for Item Bounds?

Illustrator_ufujhSIDIK

Illustrator_ZsuffrPLQ0.mp4

Ideally I'd just like to be able to select a bunch of artwork, run the script, and then just have it go, without any dialog popup.

I can try to hack this together, but if it's an easy change for you that would be awesome.

Thanks again!

Jay

from illustrator-scripts.

futuremotiondev avatar futuremotiondev commented on May 14, 2024

Edit: I edited your script (Changed the name to FitSelectionToArtboards-NoDialog.jsx) and just modified the CFG object to my desired defaults. Then ran process(CFG); instead of invoking the dialog.

Seems to work as expected, but the execution is a bit slower than the original script. Not exactly sure why. But I'm happy because it works. Here's the full code:

//@target illustrator
preferences.setBooleanPreference('ShowExternalJSXWarning', false); // Fix drag and drop a .jsx file

function main() {
  var SCRIPT = {
        name: 'Fit Selection To Artboards',
        version: 'v.0.3.4'
      },

      CFG = {
        pads: 0,
        isAll: true,
        isVisBnds: true,
        isFit: true,
        isRename: false,
        aiVers: parseInt(app.version),
        isScaleStroke: preferences.getBooleanPreference('scaleLineWeight'),
        units: getUnits(), // Active document units
        showUI: false,    // Silent mode or dialog
      };

  if (CFG.aiVers < 16) {
    alert('Error\nSorry, script only works in Illustrator CS6 and later', 'Script error');
    return;
  }

  if (!documents.length) {
    alert('Error\nOpen a document and try again', 'Script error');
    return;
  }

  if (!selection.length || selection.typename == 'TextRange') {
    alert('Error\nPlease, select one or more items', 'Script error');
    return;
  }

  // Scale factor for Large Canvas mode
  CFG.sf = activeDocument.scaleFactor ? activeDocument.scaleFactor : 1;

  process(CFG);

}

// Run processing
function process(cfg) {
  var doc = app.activeDocument,
      docAbs = doc.artboards,
      abIdx = docAbs.getActiveArtboardIndex(),
      abBnds = docAbs[abIdx].artboardRect,
      docSel = selection,
      item = docSel[0],
      coord = app.coordinateSystem,
      ruler = docAbs[abIdx].rulerOrigin;

  app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;

  if (!cfg.isAll) {
    if (cfg.isFit) {
      fitToArtboard(item, abBnds, cfg.isVisBnds, cfg.isScaleStroke, cfg.pads);
    }
    docAbs[abIdx].rulerOrigin = [0, 0];
    centerToArtboard(item, abBnds);
    docAbs[abIdx].rulerOrigin = ruler;
    if (cfg.isRename) {
      renameArtboard(item, docAbs[abIdx]);
    }
  } else {
    var emptyAbs = getEmptyArtboards(doc),
        len = Math.min(emptyAbs.length, docSel.length);

    for (var i = len - 1; i >= 0; i--) {
      item = docSel[i];
      abIdx = emptyAbs[i];
      abBnds = docAbs[abIdx].artboardRect;
      docAbs.setActiveArtboardIndex(abIdx);
      if (cfg.isFit) {
        fitToArtboard(item, abBnds, cfg.isVisBnds, cfg.isScaleStroke, cfg.pads);
      }
      ruler = docAbs[abIdx].rulerOrigin;
      docAbs[abIdx].rulerOrigin = [0, 0];
      centerToArtboard(item, abBnds);
      docAbs[abIdx].rulerOrigin = ruler;
      if (cfg.isRename) {
        renameArtboard(item, docAbs[abIdx]);
      }
    }
  }

  app.coordinateSystem = coord;
  selection = docSel;
}

// Get the ruler units of the active document
function getUnits() {
  if (!documents.length) return '';
  var key = activeDocument.rulerUnits.toString().replace('RulerUnits.', '');
  switch (key) {
    case 'Pixels': return 'px';
    case 'Points': return 'pt';
    case 'Picas': return 'pc';
    case 'Inches': return 'in';
    case 'Millimeters': return 'mm';
    case 'Centimeters': return 'cm';
    // Added in CC 2023 v27.1.1
    case 'Meters': return 'm';
    case 'Feet': return 'ft';
    case 'FeetInches': return 'ft';
    case 'Yards': return 'yd';
    // Parse new units in CC 2020-2023 if a document is saved
    case 'Unknown':
      var xmp = activeDocument.XMPString;
      if (/stDim:unit/i.test(xmp)) {
        var units = /<stDim:unit>(.*?)<\/stDim:unit>/g.exec(xmp)[1];
        if (units == 'Meters') return 'm';
        if (units == 'Feet') return 'ft';
        if (units == 'FeetInches') return 'ft';
        if (units == 'Yards') return 'yd';
        return 'px';
      }
      break;
    default: return 'px';
  }
}

// Units conversion
function convertUnits(value, currUnits, newUnits) {
  return UnitValue(value, currUnits).as(newUnits);
}

// Convert string to absolute number
function strToAbsNum(str, def) {
  if (arguments.length == 1 || def == undefined) def = 1;
  str = str.replace(/,/g, '.').replace(/[^\d.]/g, '');
  str = str.split('.');
  str = str[0] ? str[0] + '.' + str.slice(1).join('') : '';
  if (isNaN(str) || !str.length) return parseFloat(def);
  else return parseFloat(str);
}

// Fit the item to the size of the artboard
function fitToArtboard(item, abBnds, isVisBnds, isStroke, pads) {
  var type = isVisBnds ? 'visibleBounds' : 'geometricBounds';
  var bnds = [];

  if (isType(item, 'group|text')) {
    var dup = item.duplicate();
    app.executeMenuCommand('deselectall');
    selection = dup;
    outlineText(dup.pageItems ? dup.pageItems : [dup]);
    dup = selection[0];
    bnds = getVisibleBounds(dup, type);
    app.executeMenuCommand('deselectall');
    dup.remove();
  } else {
    bnds = getVisibleBounds(item, type);
  }

  var itemW = Math.abs(bnds[2] - bnds[0]),
      itemH = Math.abs(bnds[1] - bnds[3]),
      abWidth = Math.abs(abBnds[2] - abBnds[0]),
      abHeight = Math.abs(abBnds[1] - abBnds[3]);

  var ratioW = 100 * (abWidth - 2 * pads) / itemW,
      ratioH = 100 * (abHeight - 2 * pads) / itemH,
      ratio = Math.min(ratioW, ratioH);

  // X, Y, Positions, FillPatterns, FillGradients, StrokePattern, LineWidths
  item.resize(ratio, ratio, true, true, true, true, (isVisBnds || isStroke) ? ratio : 100);
}

// Create outlines
function outlineText(coll) {
  for (var i = coll.length - 1; i >= 0; i--) {
    var item = coll[i];
    if (isType(item, 'text')) {
      item.createOutline();
    } else if (isType(item, 'group')) {
      outlineText(item.pageItems);
    }
  }
}

// Get the actual "visible" bounds
// https://github.com/joshbduncan/adobe-scripts/blob/main/DrawVisibleBounds.jsx
function getVisibleBounds(obj, type) {
  if (arguments.length == 1 || type == undefined) type = 'geometricBounds';
  var doc = app.activeDocument;
  var bnds, clippedItem, tmpItem, tmpLayer;
  var curItem;
  if (obj.typename === 'GroupItem') {
    if (obj.clipped) {
      // Check all sub objects to find the clipping path
      for (var i = 0; i < obj.pageItems.length; i++) {
        curItem = obj.pageItems[i];
        if (curItem.clipping) {
          clippedItem = curItem;
          break;
        } else if (curItem.typename === 'CompoundPathItem') {
          if (!curItem.pathItems.length) {
            // Catch compound path items with no pathItems
            // via William Dowling @ github.com/wdjsdev
            tmpLayer = doc.layers.add();
            tmpItem = curItem.duplicate(tmpLayer);
            app.executeMenuCommand('deselectall');
            tmpItem.selected = true;
            app.executeMenuCommand('noCompoundPath');
            tmpLayer.hasSelectedArtwork = true;
            app.executeMenuCommand('group');
            clippedItem = selection[0];
            break;
          } else if (curItem.pathItems[0].clipping) {
            clippedItem = curItem;
            break;
          }
        }
      }
      if (!clippedItem) clippedItem = obj.pageItems[0];
      bnds = clippedItem[type];
      if (tmpLayer) {
        tmpLayer.remove();
        tmpLayer = undefined;
      }
    } else {
      // If the object is not clipped
      var subObjBnds;
      var allBoundPoints = [[], [], [], []];
      // Get the bounds of every object in the group
      for (var i = 0; i < obj.pageItems.length; i++) {
        curItem = obj.pageItems[i];
        subObjBnds = getVisibleBounds(curItem, type);
        allBoundPoints[0].push(subObjBnds[0]);
        allBoundPoints[1].push(subObjBnds[1]);
        allBoundPoints[2].push(subObjBnds[2]);
        allBoundPoints[3].push(subObjBnds[3]);
      }
      // Determine the groups bounds from it sub object bound points
      bnds = [
        Math.min.apply(Math, allBoundPoints[0]),
        Math.max.apply(Math, allBoundPoints[1]),
        Math.max.apply(Math, allBoundPoints[2]),
        Math.min.apply(Math, allBoundPoints[3]),
      ];
    }
  } else {
    bnds = obj[type];
  }
  return bnds;
}

// Place the item in the center of the artboard
function centerToArtboard(item, abBnds) {
  var bnds = item.geometricBounds,
      itemSize = {
        left: bnds[0],
        top: bnds[1],
        inLeft: bnds[0],
        inTop: bnds[1],
        inRight: bnds[2],
        inBottom: bnds[3],
        h: 0,
        w: 0
      };

  if (isType(item, 'group') && item.clipped) {
    bnds = getVisibleBounds(item, 'geometricBounds');
    itemSize.inLeft = bnds[0];
    itemSize.inTop = bnds[1];
    itemSize.inRight = bnds[2];
    itemSize.inBottom = bnds[3];
  } else if (isType(item, 'group|text')) {
    var dup = item.duplicate();
    app.executeMenuCommand('deselectall');
    selection = dup;
    outlineText(dup.pageItems ? dup.pageItems : [dup]);
    dup = selection[0];
    bnds = getVisibleBounds(dup, 'geometricBounds');
    app.executeMenuCommand('deselectall');
    itemSize.inLeft = bnds[0];
    itemSize.inTop = bnds[1];
    itemSize.inRight = bnds[2];
    itemSize.inBottom = bnds[3];
    dup.remove();
  }

  abWidth = Math.abs(abBnds[2] - abBnds[0]);
  abHeight = Math.abs(abBnds[1] - abBnds[3]);
  itemSize.h = Math.abs(itemSize.inTop - itemSize.inBottom);
  itemSize.w = Math.abs(itemSize.inRight - itemSize.inLeft);

  var left = itemSize.left - itemSize.inLeft,
      top = itemSize.top - itemSize.inTop,
      centerX = left + (abWidth - itemSize.w) / 2,
      centerY = top + (itemSize.h - abHeight) / 2;

  item.position = [centerX, centerY];
}

// Rename the artboard as an item
function renameArtboard(item, ab) {
  var name = '';

  if (isType(item, 'text') && isEmpty(item.name) && !isEmpty(item.contents)) {
    name = item.contents.slice(0, 100);
  } else if (isType(item, 'symbol') && isEmpty(item.name)) {
    name = item.symbol.name;
  } else {
    name = item.name;
  }

  if (!isEmpty(name) && ab.name !== name) ab.name = name;
}

// Get empty artboards of the document
function getEmptyArtboards(doc) {
  var out = [];
  for (var i = 0, len = doc.artboards.length; i < len; i++) {
    selection = null;
    doc.artboards.setActiveArtboardIndex(i);
    doc.selectObjectsOnActiveArtboard();
    if (!selection.length) out.push(i);
  }
  return out;
}

// Check an empty string
function isEmpty(str) {
  return str.replace(/\s/g, '').length == 0;
}

// Check the item typename by short name
function isType(item, type) {
  var regexp = new RegExp(type, 'i');
  return regexp.test(item.typename);
}

// Open link in browser
function openURL(url) {
  var html = new File(Folder.temp.absoluteURI + '/aisLink.html');
  html.open('w');
  var htmlBody = '<html><head><META HTTP-EQUIV=Refresh CONTENT="0; URL=' + url + '"></head><body> <p></body></html>';
  html.write(htmlBody);
  html.close();
  html.execute();
}

try {
  main();
} catch (e) {}

Is this change the most optimal way to do what I'm looking for? Or is there a better (or more fast) way to do this?

Thanks again,
Jay

from illustrator-scripts.

creold avatar creold commented on May 14, 2024

@futuremotiondev the speed of the script is affected by the number of artboards in the document. The script first checks which artboards are empty. The UI and No UI versions do not differ in the algorithm.

from illustrator-scripts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.