From 416fd4cbaa902fb5e47a6341608a06db37b43cc1 Mon Sep 17 00:00:00 2001 From: Sergey Osokin Date: Sun, 18 Apr 2021 17:56:31 +0500 Subject: [PATCH] Update DuplicateArtboardsLight.jsx Performance optimization --- jsx/DuplicateArtboardsLight.jsx | 189 ++++++++++++++++---------------- 1 file changed, 97 insertions(+), 92 deletions(-) diff --git a/jsx/DuplicateArtboardsLight.jsx b/jsx/DuplicateArtboardsLight.jsx index ffee457..8a6c59f 100644 --- a/jsx/DuplicateArtboardsLight.jsx +++ b/jsx/DuplicateArtboardsLight.jsx @@ -4,25 +4,29 @@ Requirements: Adobe Illustrator CS6 and later Date: October, 2020 Author: Sergey Osokin, email: hi@sergosokin.ru - + Installation: https://github.com/creold/illustrator-scripts#how-to-run-scripts - + Versions: 0.1 Initial version 0.2 Fixed: bounds checking of the Illustrator canvas; position of the first copy 0.2.1 Fixed script didn't run if the layers were locked 0.2.2 Performance optimization - - Donate (optional): If you find this script helpful, you can buy me a coffee - via PayPal http://www.paypal.me/osokin/usd - + + Donate (optional): + If you find this script helpful, you can buy me a coffee + - via PayPal http://www.paypal.me/osokin/usd + - via QIWI https://qiwi.com/n/OSOKIN​ + - via YooMoney https://yoomoney.ru/to/410011149615582​ + NOTICE: + Tested with Adobe Illustrator CC 2018-2021 (Mac), 2021 (Win). This script is provided "as is" without warranty of any kind. Free to use, not for sale. - + Released under the MIT license. http://opensource.org/licenses/mit-license.php - + Check other author's scripts: https://github.com/creold */ @@ -48,15 +52,15 @@ var SCRIPT_NAME = 'Duplicate Atboards Light', OVER_OBJ = 2500, // The amount of objects, when the script can run slowly CNVS_SIZE = 16383, // Illustrator canvas max bounds, px OVER_COPIES = 10, // When the number of copies >, full-screen mode is enabled - DEF_DLG_OPACITY = 0.97, // UI window opacity. Range 0-1 + DLG_OPACITY = 0.96, // UI window opacity. Range 0-1 FIELD_SIZE = [0, 0, 60, 30], TITLE_SIZE = [0, 0, 120, 30]; // EN-RU localized messages -var LANG_ERR_DOC = { en: 'Error\nOpen a document and try again.', - ru: 'Ошибка\nОткройте документ и запустите скрипт.' }, - LANG_ERR_VER = { en: 'Error\nSorry, script only works in Illustrator CS6 and later.', - ru: 'Ошибка\nСкрипт работает в Illustrator CS6 и выше.' }, +var LANG_ERR_DOC = { en: 'Error\nOpen a document and try again', + ru: 'Ошибка\nОткройте документ и запустите скрипт' }, + LANG_ERR_VER = { en: 'Error\nSorry, script only works in Illustrator CS6 and later', + ru: 'Ошибка\nСкрипт работает в Illustrator CS6 и выше' }, LANG_ERR_COPIES = { en: 'Error\nMaximum amount of copies in document: ', ru: 'Ошибка\nМаксимальное количество копий в документе: ' }, LANG_SLOW = { en: 'In the document over ' + OVER_OBJ + ' objects. The script can run slowly', @@ -71,29 +75,29 @@ function main() { if (AI_VER < 16) { alert(LANG_ERR_VER); return; - } + } - if (documents.length == 0) { + if (!documents.length) { alert(LANG_ERR_DOC); return; } var doc = app.activeDocument, - maxCopies = 1000 - doc.artboards.length, // 1000 is max artboards + maxCopies = ((AI_VER >= 22) ? 1000 : 100) - doc.artboards.length, // Artboards limit currAbIdx = doc.artboards.getActiveArtboardIndex(), abArr = [], copies = spacing = 0; - + // Collect artboards names for dropdown menu - for (var i = 0; i < doc.artboards.length; i++) { + for (var i = 0, aLen = doc.artboards.length; i < aLen; i++) { abArr.push((i + 1) + ': ' + doc.artboards[i].name); } // Main Window - var dialog = new Window('dialog', SCRIPT_NAME + ' ' + SCRIPT_VERSION, undefined); + var dialog = new Window('dialog', SCRIPT_NAME + ' ' + SCRIPT_VERSION); dialog.orientation = 'column'; dialog.alignChildren = ['fill', 'center']; - dialog.opacity = DEF_DLG_OPACITY; + dialog.opacity = DLG_OPACITY; // Input fields var abGroup = dialog.add('group'); @@ -102,7 +106,7 @@ function main() { abGroup.add('statictext', undefined, LANG_ARTBOARD); var abIdx = abGroup.add('dropdownlist', TITLE_SIZE, abArr); abIdx.selection = currAbIdx; - + var fieldGroup = dialog.add('group'); fieldGroup.orientation = 'row'; fieldGroup.alignChildren = ['fill', 'center']; @@ -111,7 +115,7 @@ function main() { titlesGroup.orientation = 'column'; var copiesTitle = titlesGroup.add('statictext', TITLE_SIZE, LANG_COPIES); titlesGroup.add('statictext', TITLE_SIZE, LANG_SPACING + ', ' + getDocUnit()); - + var inputsGroup = fieldGroup.add('group'); inputsGroup.orientation = 'column'; var copiesVal = inputsGroup.add('edittext', FIELD_SIZE, DEF_COPIES); @@ -133,13 +137,13 @@ function main() { copyright.enabled = false; loadSettings(); - + spacing = convertUnits( convertToNum(spacingVal.text, SPACING_MIN) + getDocUnit(), 'px' ); currAbIdx = doc.artboards.getActiveArtboardIndex(); - var abCoord = getArtboardCoordinates(currAbIdx); + var abCoord = getArtboardCoordinates(currAbIdx, TMP_LAYER_NAME); var overCnvsSize = isOverCnvsBounds(abCoord, maxCopies, spacing); - + copiesTitle.text = LANG_COPIES + overCnvsSize.copies + ')'; if (convertToNum(copiesVal.text, DEF_COPIES) > overCnvsSize.copies) { copiesVal.text = overCnvsSize.copies; @@ -147,7 +151,7 @@ function main() { shiftInputNumValue(copiesVal, DEF_COPIES); shiftInputNumValue(spacingVal, SPACING_MIN); - + // Change listeners copiesVal.onChange = spacingVal.onChange = recalcCopies; copiesVal.onChanging = spacingVal.onChanging = recalcCopies; @@ -163,13 +167,12 @@ function main() { } dialog.onClose = function() { - // Remove temp layer with artboards numbers + // Remove temp layer try { - var layerToRm = doc.layers.getByName(TMP_LAYER_NAME); - layerToRm.remove(); + doc.layers.getByName(TMP_LAYER_NAME).remove(); } catch (e) {} } - + ok.onClick = okClick; function okClick() { @@ -181,7 +184,7 @@ function main() { alert(LANG_ERR_COPIES + maxCopies); return; } - + selection = null; var userView = doc.views[0].screenMode; @@ -189,7 +192,7 @@ function main() { unlockLayers(doc.layers); removeNote(doc.layers, L_KEY, H_KEY); // Сlear Note after previous run saveItemsState(doc.layers, L_KEY, H_KEY); - + // Copy Artwork doc.selectObjectsOnActiveArtboard(); app.copy(); @@ -209,35 +212,35 @@ function main() { doc.views[0].screenMode = userView; saveSettings(); app.userInteractionLevel = UserInteractionLevel.DISPLAYALERTS; - + dialog.close(); } - + dialog.center(); dialog.show(); - + /** * Recalculate the maximum amount of copies at a given spacing */ function recalcCopies() { spacing = convertUnits( convertToNum(spacingVal.text, SPACING_MIN) + getDocUnit(), 'px' ); currAbIdx = doc.artboards.getActiveArtboardIndex(); - abCoord = getArtboardCoordinates(currAbIdx); + abCoord = getArtboardCoordinates(currAbIdx, TMP_LAYER_NAME); overCnvsSize = isOverCnvsBounds(abCoord, maxCopies, spacing); copiesTitle.text = LANG_COPIES + overCnvsSize.copies + ')'; - if (convertToNum(copiesVal.text, DEF_COPIES) > overCnvsSize.copies) { + if (convertToNum(copiesVal.text, DEF_COPIES) > overCnvsSize.copies) { copiesVal.text = overCnvsSize.copies; } - if (convertToNum(copiesVal.text, DEF_COPIES) < 0) { + if (convertToNum(copiesVal.text, DEF_COPIES) < 0) { copiesVal.text = 0; } } /** * Use Up / Down arrow keys (+ Shift) for change value - * @param {object} item - input text field - * @param {number} min - minimal input value + * @param {object} item input text field + * @param {number} min minimal input value */ function shiftInputNumValue(item, min) { item.addEventListener('keydown', function (kd) { @@ -271,7 +274,7 @@ function main() { $file.write(data); $file.close(); } - + /** * Load input data from file */ @@ -292,10 +295,10 @@ function main() { /** * Unlock all Layers & Sublayers - * @param {object} _layers - the collection of layers + * @param {object} _layers the collection of layers */ function unlockLayers(_layers) { - for (var i = 0; i < _layers.length; i++) { + for (var i = 0, len = _layers.length; i < len; i++) { if (_layers[i].locked) _layers[i].locked = false; if (_layers[i].layers.length) unlockLayers(_layers[i].layers); } @@ -303,18 +306,20 @@ function unlockLayers(_layers) { /** * Remove keyword from Note in Attributes panel - * @param {object} _layers - the collection of layers - * @param {string} lKey - keyword for locked items - * @param {string} hKey - keyword for hidden items + * @param {object} _layers the collection of layers + * @param {string} lKey keyword for locked items + * @param {string} hKey keyword for hidden items */ function removeNote(_layers, lKey, hKey) { var regexp = new RegExp(lKey + '|' + hKey, 'gi'); - for (var i = 0; i < _layers.length; i++) { + for (var i = 0, len = _layers.length; i < len; i++) { var currLayer = _layers[i], allItems = []; - if (currLayer.layers.length > 0) removeNote(currLayer.layers, lKey, hKey); + if (currLayer.layers.length > 0) { + removeNote(currLayer.layers, lKey, hKey); + } getItems(currLayer.pageItems, allItems); - for (var j = 0; j < allItems.length; j++) { + for (var j = 0, iLen = allItems.length; j < iLen; j++) { var currItem = allItems[j]; currItem.note = currItem.note.replace(regexp, ''); } @@ -323,19 +328,19 @@ function removeNote(_layers, lKey, hKey) { /** * Save information about locked & hidden pageItems & layers - * @param {object} _layers - the collection of layers - * @param {string} lKey - keyword for locked items - * @param {string} hKey - keyword for hidden items + * @param {object} _layers the collection of layers + * @param {string} lKey keyword for locked items + * @param {string} hKey keyword for hidden items */ function saveItemsState(_layers, lKey, hKey) { var allItems = []; - for (var i = 0; i < _layers.length; i++) { + for (var i = 0, len = _layers.length; i < len; i++) { var currLayer = _layers[i]; - if (currLayer.layers.length > 0) { + if (currLayer.layers.length > 0) { saveItemsState(currLayer.layers, lKey, hKey); } getItems(currLayer.pageItems, allItems); - for (var j = 0; j < allItems.length; j++) { + for (var j = 0, iLen = allItems.length; j < iLen; j++) { var currItem = allItems[j]; if (currItem.locked) { currItem.note += lKey; @@ -352,19 +357,19 @@ function saveItemsState(_layers, lKey, hKey) { /** * Restoring locked & hidden pageItems & layers - * @param {object} _layers - the collection of layers - * @param {string} lKey - keyword for locked items - * @param {string} hKey - keyword for hidden items + * @param {object} _layers the collection of layers + * @param {string} lKey keyword for locked items + * @param {string} hKey keyword for hidden items */ function restoreItemsState(_layers, lKey, hKey) { var allItems = []; - for (var i = 0; i < _layers.length; i++) { + for (var i = 0, len = _layers.length; i < len; i++) { var currLayer = _layers[i]; - if (currLayer.layers.length > 0) { + if (currLayer.layers.length > 0) { restoreItemsState(currLayer.layers, lKey, hKey); } getItems(currLayer.pageItems, allItems); - for (var j = 0; j < allItems.length; j++) { + for (var j = 0, iLen = allItems.length; j < iLen; j++) { var currItem = allItems[j]; if (currItem.note.match(lKey) != null) currItem.locked = true; if (currItem.note.match(hKey) != null) currItem.hidden = true; @@ -374,11 +379,11 @@ function restoreItemsState(_layers, lKey, hKey) { /** * Collect items - * @param {object} obj - collection of items - * @param {array} arr - output array with childrens + * @param {object} obj collection of items + * @param {array} arr output array with childrens */ function getItems(obj, arr) { - for (var i = 0; i < obj.length; i++) { + for (var i = 0, len = obj.length; i < len; i++) { var currItem = obj[i]; try { switch (currItem.typename) { @@ -396,8 +401,8 @@ function getItems(obj, arr) { /** * Add zero to the file name before the indexes are less then size - * @param {number} number - copy number - * @param {number} size - length of the amount of copies + * @param {number} number copy number + * @param {number} size length of the amount of copies * @return {string} copy number with pre-filled zeros */ function fillZero(number, size) { @@ -407,33 +412,33 @@ function fillZero(number, size) { /** * Trick with temp pathItem to get the absolute coordinate of the artboard. Thanks to @moodyallen - * @param {number*} abIdx - current artboard index - * @return {object} absolute coordinates of the artboard + * @param {number*} abIdx current artboard index + * @return {object} absolute coordinates of the artboard */ -function getArtboardCoordinates(abIdx) { +function getArtboardCoordinates(abIdx, lyrName) { var doc = app.activeDocument, thisAbRect = doc.artboards[abIdx].artboardRect, // The selected artboard size tmpLayer; try { - tmpLayer = doc.layers.getByName(TMP_LAYER_NAME); + tmpLayer = doc.layers.getByName(lyrName); } catch (e) { tmpLayer = doc.layers.add(); - tmpLayer.name = TMP_LAYER_NAME; + tmpLayer.name = lyrName; } - + var fakePath = tmpLayer.pathItems.add(); var cnvsDelta = 1 + ((fakePath.position[0] * 2 - 16384) - (fakePath.position[1] * 2 + 16384)) / 2; var cnvsTempPath = tmpLayer.pathItems.rectangle(fakePath.position[0] - cnvsDelta, fakePath.position[1] + cnvsDelta, 300, 300); cnvsTempPath.filled = false; cnvsTempPath.stroked = false; - + // Create a rectangle with the same size as the artboard var top = thisAbRect[1], left = thisAbRect[0], width = thisAbRect[2] - thisAbRect[0], height = thisAbRect[1] - thisAbRect[3]; - + var abTempPath = tmpLayer.pathItems.rectangle(top, left, width, height); abTempPath.stroked = false; abTempPath.filled = false; @@ -443,7 +448,7 @@ function getArtboardCoordinates(abIdx) { absTop = Math.floor(cnvsTempPath.position[1] - abTempPath.position[1]), absBottom = absTop + height, absRight = absLeft + width; - + fakePath.remove(); abTempPath.remove(); cnvsTempPath.remove(); @@ -454,15 +459,15 @@ function getArtboardCoordinates(abIdx) { /** * Find out if the amount of copies over the canvas width - * @param {object} coord - coordinates of the selected artboard - * @param {number} copies - amount of copies - * @param {number} spacing - distance between copies + * @param {object} coord coordinates of the selected artboard + * @param {number} copies amount of copies + * @param {number} spacing distance between copies * @return {object} information about the extreme possible artboard */ -function isOverCnvsBounds(coord, copies, spacing) { +function isOverCnvsBounds(coord, copies, spacing) { var lastAbRight = coord.right + (spacing + coord.right - coord.left) * copies, tempEdge = lastAbRight; - + // Get a safe amount of copies for (var i = copies; i >= 0; i--) { if (tempEdge <= CNVS_SIZE) break; @@ -474,10 +479,10 @@ function isOverCnvsBounds(coord, copies, spacing) { /** * Duplicate the selected artboard. Based on the idea of @Silly-V - * @param {number} thisAbIdx - current artboard index - * @param {number} spacing - distance between copies - * @param {string} suffix - copy name suffix - * @param {number} count - current copy number + * @param {number} thisAbIdx current artboard index + * @param {number} spacing distance between copies + * @param {string} suffix copy name suffix + * @param {number} count current copy number */ function duplicateArtboard(thisAbIdx, spacing, suffix, count) { var doc = app.activeDocument, @@ -524,8 +529,8 @@ function getDocUnit() { } /** - * @param {string} value - input data - * @param {string} def - default units + * @param {string} value input data + * @param {string} def default units * @return {string} input data units */ function getUnits(value, def) { @@ -536,9 +541,9 @@ function getUnits(value, def) { /** * Сonvert to the specified units of measurement - * @param {string} value - input data - * @param {string} newUnit - specified units - * @return {number} converted data + * @param {string} value input data + * @param {string} newUnit specified units + * @return {number} converted data */ function convertUnits(value, newUnit) { if (value === undefined) return value; @@ -585,9 +590,9 @@ function convertUnits(value, newUnit) { /** * Convert any input data to a number - * @param {string} str - input data - * @param {number} def - default value if the input data don't contain numbers - * @return {number} + * @param {string} str input data + * @param {number} def default value if the input data don't contain numbers + * @return {number} */ function convertToNum(str, def) { // Remove unnecessary characters