├── .gitignore ├── LICENSE ├── puzzleClipper.jsx ├── clippBottom.jsx ├── inlineSVGToAI.jsx ├── compoundFix.jsx ├── forceCloseOtherDocuments.jsx ├── createRectangleOnArtboard.jsx ├── artboardsRotateWithObjects.jsx ├── batchTextEdit.jsx ├── README.md ├── artboardItemsMoveToNewLayer.jsx ├── random-dash.jsx ├── minusOffset.jsx ├── createArtboardsFromTheSelection.jsx ├── replaceItems.jsx ├── artboardsResizeWithObjects.jsx ├── bigBang.jsx ├── transferSwatches.jsx ├── long_shadow.jsx ├── harmonizer.jsx ├── rich_glitch.jsx ├── niceSlice.jsx ├── optimizero.jsx └── circular.jsx /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Alexander Ladygin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /puzzleClipper.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CS5+ 5 | Name: puzzleClipper.jsx; 6 | Copyright (c) 2018 7 | 8 | */ 9 | #target illustrator 10 | app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS; 11 | 12 | var items = selection, 13 | i = items.length - 1, 14 | target = selection[i], 15 | isGroup = false; 16 | 17 | if (i > 0) { 18 | if (i === 1 && selection[0].typename === 'GroupItem') { 19 | items = selection[0].pageItems; 20 | i = items.length; 21 | isGroup = selection[0]; 22 | } 23 | 24 | while (i--) { 25 | // create and move to group 26 | var group = activeDocument.groupItems.add(); 27 | group.move((isGroup ? target : items[i]), ElementPlacement[(isGroup ? 'PLACEBEFORE' : 'PLACEAFTER')]); 28 | 29 | // duplicate target object and move items 30 | target.duplicate().moveToBeginning(group); 31 | items[i].moveToBeginning(group); 32 | 33 | // set properties 34 | group.clipped = true; 35 | if (!isGroup) items[i].clipping = true; 36 | } 37 | 38 | if (isGroup) isGroup.remove(); 39 | target.remove(); 40 | } 41 | -------------------------------------------------------------------------------- /clippBottom.jsx: -------------------------------------------------------------------------------- 1 | // script.name = Bottomclipper.jsx; 2 | // script.required = at least two paths selected, BOTTOM path is the clipping mask; 3 | // script.parent = Herman van Boeijen, www.nimbling.com // 22-12-2014; 4 | // *** LIMITED TO A SINGLE STROKE AND/OR FILL OF THE CLIPPING OBJECT*** 5 | // Big thanks to CarlosCanto and MuppetMark on the Adobe Illustrator Scripting Forums 6 | // special modification for bundling with the TrimMasks.jsx script by Sergey Osokin (https://github.com/creold/illustrator-scripts#trimmasks) 7 | 8 | function start (sel, count, mask) { 9 | if (count) { 10 | if(activeDocument.activeLayer.locked || !activeDocument.activeLayer.visible){ 11 | alert('Please select objects on an unlocked and visible layer!'); 12 | } else { 13 | if (mask.typename === 'GroupItem' && mask.clipped) { 14 | for (i = count - 2; i >= 0; i--) { 15 | sel[i].move (mask, ElementPlacement.PLACEATBEGINNING); 16 | } 17 | return; 18 | } 19 | 20 | if (mask.typename === 'CompoundPathItem') { 21 | mask = sel[count - 1].pathItems[0]; 22 | } 23 | 24 | for (i = count - 1 ; i >= 0; i--) { 25 | sel[i].move(sel[count - 1], ElementPlacement.PLACEAFTER); 26 | } 27 | 28 | app.executeMenuCommand('makeMask'); 29 | 30 | if (mask.typename === 'CompoundPathItem') { 31 | mask = mask.pageItems[0].pathItems[0]; 32 | } 33 | } 34 | } 35 | } 36 | 37 | if (!app.documents.length) { 38 | alert('You must open at least one document.'); 39 | } else if (selection.length <= 1) { 40 | alert('Please select two or more objects!'); 41 | } else { 42 | var sel = activeDocument.selection, 43 | clipObjOriginal = sel[sel.length - 1], 44 | clipObj = clipObjOriginal.duplicate(clipObjOriginal, ElementPlacement.PLACEBEFORE); 45 | 46 | clipObjOriginal.selected = false; 47 | 48 | start(selection, selection.length, clipObj); 49 | } -------------------------------------------------------------------------------- /inlineSVGToAI.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Program version: Adobe Illustrator CS5+ 4 | Name: inlineSVGToAI.jsx; 5 | 6 | Author: Alexander Ladygin, email: i@ladygin.pro 7 | Thanks for refactoring and testing - Sergey Osokin, email: hi@sergosokin.ru 8 | Copyright (c) 2018 9 | 10 | *** 11 | 12 | Instruction for use: 13 | 1. Run script 14 | 2. Paste your svg code in textarea 15 | 3. Press button "Paste" 16 | */ 17 | 18 | #target illustrator 19 | app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS; 20 | 21 | function main() { 22 | if (app.documents.length == 0) { 23 | alert("Error: \nOpen a document and try again."); 24 | return; 25 | } 26 | uiDialog().show(); 27 | } 28 | 29 | // Create dialog window 30 | function uiDialog() { 31 | var win = new Window("dialog", "Inline SVG To AI \u00A9 www.ladyginpro.ru", undefined), 32 | winPanel = win.add("panel"); 33 | winPanel.alignChildren = ['fill', 'fill']; 34 | 35 | // Field for pasting the SVG code 36 | var winSVGCodeTitle = winPanel.add("statictext", [0, 0, 200, 15], "Please paste your svg code:"), 37 | SVGCode = winPanel.add("edittext", [0, 0, 200, 50], "", { multiline: true, scrolling: true }), 38 | insertOpen = winPanel.add("checkbox", undefined, 'Insert through "Open" (without crash AI)'); 39 | insertOpen.value = true; 40 | SVGCode.active = true; // Set state 41 | 42 | // Buttons 43 | var winButtonsGroup = win.add("group"), 44 | closeButton = winButtonsGroup.add("button", [0, 0, 100, 30], "Cancel"), 45 | pasteButton = winButtonsGroup.add("button", [0, 0, 100, 30], "Paste"); 46 | 47 | 48 | // Close window 49 | closeButton.onClick = function () { 50 | win.close(); 51 | }; 52 | 53 | // Paste button action 54 | pasteButton.onClick = function () { 55 | var code = SVGCode.text; 56 | if (code) { 57 | importSVG(code); 58 | win.close(); 59 | } else { 60 | alert("You didn't insert the SVG code."); 61 | } 62 | }; 63 | 64 | function importSVG(string) { 65 | var svgFileName = "inlineSVGtoAI.svg", 66 | svgFile = new File("" + Folder.temp + "/" + svgFileName), 67 | backDoc = activeDocument; 68 | 69 | svgFile.open("w"); 70 | svgFile.write(string); 71 | svgFile.close(); 72 | if (!insertOpen.value && (activeDocument.importFile instanceof Function)) { 73 | activeDocument.importFile(svgFile, false, false, false); 74 | } 75 | else { 76 | app.open(svgFile); 77 | var l = activeDocument.layers, 78 | i = l.length; 79 | while (i--) { l[i].hasSelectedArtwork = true; } 80 | app.copy(); 81 | activeDocument.close(SaveOptions.DONOTSAVECHANGES); 82 | backDoc.activate(); 83 | app.paste(); 84 | } 85 | $.sleep(500); 86 | svgFile.remove(); 87 | } 88 | 89 | return win; 90 | } 91 | 92 | 93 | function showError(err) { 94 | if (confirm(scriptName + ": an unknown error has occurred.\n" + 95 | "Would you like to see more information?", true, "Unknown Error")) { 96 | alert(err + ": on line " + err.line, "Script Error", true); 97 | } 98 | } 99 | 100 | try { 101 | main(); 102 | } catch (e) { 103 | showError(e); 104 | } -------------------------------------------------------------------------------- /compoundFix.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ (presumably in Adobe Illustrator CS6 - did not test) 5 | Name: compoundFix.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | if (app.executeMenuCommand instanceof Function) { 12 | if (activeDocument.compoundPathItems.length) { 13 | var win = new Window('dialog', 'CompoundFix \u00A9 www.ladyginpro.ru', undefined); 14 | win.orientation = 'column'; 15 | win.alignChildren = ['fill', 'fill']; 16 | 17 | var globalGroup = win.add('group'), 18 | panel = globalGroup.add('panel'); 19 | panel.orientation = 'column'; 20 | panel.alignChildren = 'fill'; 21 | panel.margins = 20; 22 | 23 | var radioSelection = panel.add('radiobutton', undefined, 'Selection'), 24 | radioAll = panel.add('radiobutton', undefined, 'All Compounds'); 25 | radioAll.value = true; 26 | 27 | var winButtons = globalGroup.add('group'); 28 | winButtons.orientation = 'column'; 29 | winButtons.alignChildren = 'fill'; 30 | 31 | var cancel = winButtons.add('button', [0, 0, 30, 25], 'Cancel'); 32 | cancel.helpTip = 'Press Esc to Close'; 33 | cancel.onClick = function () { win.close(); } 34 | 35 | var ok = winButtons.add('button', undefined, 'Run fix'); 36 | ok.helpTip = 'Press Enter to Run'; 37 | ok.onClick = compoundFixAction; 38 | ok.active = true; 39 | 40 | var progressBar = win.add('progressbar', [0, 0, 110, 5]), 41 | progressBarCounter = 100; 42 | progressBar.value = 0; 43 | progressBar.minvalue = 0; 44 | progressBar.maxvalue = progressBarCounter; 45 | 46 | function compoundFixAction() { 47 | globalGroup.enabled = false; 48 | function __ungroup (__items) { 49 | var l = __items.length; 50 | for (var i = 0; i < l; i++) { 51 | if (__items[i].typename === 'GroupItem') { 52 | var j = __items[i].pageItems.length; 53 | while (j--) { 54 | __items[i].pageItems[0].locked = __items[i].pageItems[0].hidden = false; 55 | __items[i].pageItems[0].moveBefore(__items[i]); 56 | } 57 | __items[i].remove(); 58 | } 59 | } 60 | } 61 | 62 | function compoundFix (item, isHidden, isLocked) { 63 | if (isHidden) item.hidden = false; 64 | if (isLocked) item.locked = false; 65 | 66 | selection = [item]; 67 | app.executeMenuCommand('noCompoundPath'); 68 | __ungroup(selection); 69 | app.executeMenuCommand('compoundPath'); 70 | 71 | if (isHidden) selection[0].hidden = true; 72 | if (isLocked) selection[0].locked = true; 73 | selection = null; 74 | } 75 | 76 | function compoundPathItemsNormalize (items) { 77 | var i = items.length; 78 | progressBarCounter /= i; 79 | while (i--) { 80 | if (items[i].typename === 'GroupItem') { 81 | compoundPathItemsNormalize(items[i].pageItems); 82 | } 83 | else if (items[i].typename === 'CompoundPathItem') { 84 | compoundFix(items[i], radioAll.value ? items[i].hidden : false, radioAll.value ? items[i].locked : false); 85 | } 86 | progressBar.value += progressBarCounter; 87 | win.update(); 88 | } 89 | } 90 | 91 | var selectionBak = selection; 92 | compoundPathItemsNormalize(radioSelection.value ? selection : activeDocument.compoundPathItems); 93 | selection = selectionBak; 94 | win.close(); 95 | } 96 | 97 | win.center(); 98 | win.show(); 99 | } 100 | else { 101 | alert('Compound path items looks fine ;)'); 102 | } 103 | } 104 | else { 105 | alert('This version of illustrator is not supported!'); 106 | } -------------------------------------------------------------------------------- /forceCloseOtherDocuments.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ 5 | Name: forceCloseOtherDocuments.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | function getCustomNumbers ($str, items, returnItems) { 12 | var __num = $str.replace(/ /g, '').replace(/[^-0-9^,]/gim,'').split(','), 13 | $maxItems = items.length, 14 | j = __num.length, 15 | arr = []; 16 | 17 | function getNumbersBetweenMinMax (min, max) { 18 | var numbers = []; 19 | for (var n = min; n <= max; n++) { 20 | if (n < $maxItems) { 21 | numbers.push(returnItems ? items[n] : n); 22 | } 23 | } 24 | return numbers; 25 | } 26 | 27 | while (j--) { 28 | if (__num[j].indexOf('-') > -1) { 29 | var values = __num[j].split('-'), 30 | min = parseInt(values[0]), 31 | max = parseInt(values[1]); 32 | 33 | if (!isNaN(min) && !isNaN(max)) arr = arr.concat(getNumbersBetweenMinMax(min - 1, max - 1)); 34 | } 35 | else { 36 | var __val = parseInt(__num[j]); 37 | if (!isNaN(__val) && __val <= $maxItems) { 38 | arr.push(returnItems ? items[__val - 1] : __val - 1); 39 | } 40 | } 41 | } 42 | 43 | return arr; 44 | } 45 | 46 | function __documentsClose (save_options, userOptions) { 47 | // documentsDontClose => [Document] || [Array] 48 | 49 | var options = {}; 50 | options.not = userOptions.not || []; 51 | options.document = userOptions.document || null; 52 | 53 | if (app.documents.length) { 54 | save_options = (typeof save_options === 'string' && save_options.length ? save_options : 'PROMPTTOSAVECHANGES').toLowerCase(); 55 | 56 | if ((save_options.slice(0, 1) === 'n') || (save_options.slice(0, 1) === 'd')) save_options = 'DONOTSAVECHANGES'; 57 | else if (save_options.slice(0, 1) === 's') save_options = 'SAVECHANGES'; 58 | else save_options = 'PROMPTTOSAVECHANGES'; 59 | 60 | options.not = (options.not.typename === 'Document' ? [options.not] : options.not.typename === 'Documents' ? options.not : options.not); 61 | var l = options.not.length; 62 | 63 | if (!options.documents) { 64 | var i = app.documents.length; 65 | while (i--) { 66 | var check = true; 67 | for (var j = 0; j < l; j++) { if (app.documents[i] === options.not[j]) check = false; } 68 | if (check) app.documents[i].close(SaveOptions[save_options.toUpperCase()]); 69 | } 70 | } 71 | else { 72 | options.document.close(SaveOptions[save_options.toUpperCase()]); 73 | } 74 | } 75 | else { 76 | throw new Error('Documents not found!'); 77 | } 78 | }; 79 | 80 | function __documentsForceCloseOther (documentsDontClose) { 81 | if (app.documents.length) { 82 | documentsDontClose = documentsDontClose instanceof Array ? documentsDontClose.concat([app.activeDocument]) : [app.activeDocument]; 83 | return __documentsClose('not', { 84 | not: documentsDontClose 85 | }); 86 | } 87 | else { 88 | throw new Error('Documents not found!'); 89 | } 90 | }; 91 | 92 | function getDocumentToList() { 93 | var result = [], l = app.documents.length; 94 | for (i = 0; i < l; i++) { 95 | result.push((i + 1) + '. ' + app.documents[i].name); 96 | } 97 | return result; 98 | } 99 | 100 | var win = new Window('dialog', 'Force close others \u00A9 www.ladyginpro.ru', undefined); 101 | win.orientation = 'column'; 102 | win.alignChildren = ['fill', 'fill']; 103 | 104 | var panel = win.add('panel', undefined, 'Exclude documents:'); 105 | panel.orientation = 'column'; 106 | panel.alignChildren = ['fill', 'fill']; 107 | panel.margins = 20; 108 | 109 | var inputPlaceholder = panel.add('statictext', undefined, 'Example: "1, 2, 3" or "1, 2-5, 9"'), 110 | inputDocuments = panel.add('edittext', undefined, 1); 111 | 112 | var docGroup = panel.add('group'); 113 | docGroup.orientation = 'row'; 114 | 115 | 116 | var docPlaceholder = docGroup.add('statictext', undefined, 'Only read'), 117 | docList = docGroup.add('dropdownlist', undefined, getDocumentToList()); 118 | docList.maximumSize = [115, 25]; 119 | docList.selection = 0; 120 | 121 | var winButtons = win.add('group'); 122 | winButtons.orientation = 'row'; 123 | winButtons.alignChildren = ['fill', 'fill']; 124 | 125 | var cancel = winButtons.add('button', undefined, 'Cancel'); 126 | cancel.helpTip = 'Press Esc to Close'; 127 | cancel.onClick = function () { win.close(); } 128 | 129 | var ok = winButtons.add('button', undefined, 'OK'); 130 | ok.helpTip = 'Press Enter to Run'; 131 | ok.onClick = startAction; 132 | ok.active = true; 133 | 134 | win.center(); 135 | win.show(); 136 | 137 | function startAction() { 138 | if (app.documents.length) { 139 | __documentsForceCloseOther(getCustomNumbers(inputDocuments.text, app.documents, true)); 140 | } 141 | win.close(); 142 | } -------------------------------------------------------------------------------- /createRectangleOnArtboard.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Program version: Adobe Illustrator CS5+ 4 | Name: createRectangleOnArtboard.jsx; 5 | 6 | Author: Alexander Ladygin, email: i@ladygin.pro 7 | 8 | Copyright (c) 2019 9 | www.ladyginpro.ru 10 | 11 | */ 12 | 13 | var scriptName = 'CROA', 14 | copyright = ' \u00A9 www.ladyginpro.ru', 15 | settingFile = { 16 | name: scriptName + '__setting.json', 17 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 18 | }; 19 | 20 | if (app.documents.length) { 21 | function getCustomNumbers ($str, items, returnItems) { 22 | var __num = $str.replace(/ /g, '').replace(/[^-0-9^,]/gim,'').split(','), 23 | $maxItems = items.length, 24 | l = __num.length, 25 | arr = []; 26 | 27 | function getNumbersBetweenMinMax (min, max) { 28 | var numbers = []; 29 | for (var n = min; n <= max; n++) { 30 | if (n < $maxItems) { 31 | numbers.push(returnItems ? items[n] : n); 32 | } 33 | } 34 | return numbers; 35 | } 36 | 37 | for (var j = 0; j < l; j++) { 38 | if (__num[j].indexOf('-') > -1) { 39 | var values = __num[j].split('-'), 40 | min = parseInt(values[0]), 41 | max = parseInt(values[1]); 42 | 43 | if (!isNaN(min) && !isNaN(max)) arr = arr.concat(getNumbersBetweenMinMax(min - 1, max - 1)); 44 | } 45 | else { 46 | var __val = parseInt(__num[j]); 47 | if (!isNaN(__val) && __val <= $maxItems) { 48 | arr.push(returnItems ? items[__val - 1] : __val - 1); 49 | } 50 | } 51 | } 52 | 53 | return arr; 54 | } 55 | 56 | 57 | function createRectangleOnArtboard (__artNumbers) { 58 | if (__artNumbers && __artNumbers.length) { 59 | var l = __artNumbers.length; 60 | 61 | for (var i = 0; i < l; i++) { 62 | var rect = activeDocument.artboards[__artNumbers[i]].artboardRect, 63 | shape = activeDocument.activeLayer.pathItems.rectangle(rect[1], rect[0], rect[2] - rect[0], rect[1] - rect[3]); 64 | 65 | shape.fillColor = activeDocument.defaultFillColor; 66 | } 67 | } 68 | } 69 | 70 | var win = new Window('dialog', 'Rectangle On Art \u00A9 www.ladyginpro.ru', undefined); 71 | win.orientation = 'column'; 72 | win.alignChildren = ['fill', 'fill']; 73 | 74 | var panel = win.add('panel', undefined, 'Artboards:'); 75 | panel.orientation = 'column'; 76 | panel.alignChildren = ['fill', 'fill']; 77 | panel.margins = 20; 78 | 79 | var groupRadio = panel.add('group'); 80 | groupRadio.orientation = 'row'; 81 | 82 | var allArtboardsRadio = groupRadio.add('radiobutton', undefined, 'All'), 83 | customArtboardsRadio = groupRadio.add('radiobutton', undefined, 'Custom'); 84 | allArtboardsRadio.value = true; 85 | allArtboardsRadio.onClick = function () { customArts.enabled = false; }; 86 | customArtboardsRadio.onClick = function () { customArts.enabled = true; }; 87 | 88 | var customArts = panel.add('edittext', undefined, activeDocument.artboards.getActiveArtboardIndex() + 1); 89 | customArts.enabled = false; 90 | 91 | var winButtons = win.add('group'); 92 | winButtons.orientation = 'row'; 93 | winButtons.alignChildren = ['fill', 'fill']; 94 | 95 | var cancel = winButtons.add('button', undefined, 'Cancel'); 96 | cancel.helpTip = 'Press Esc to Close'; 97 | cancel.onClick = function () { win.close(); } 98 | 99 | var ok = winButtons.add('button', undefined, 'OK'); 100 | ok.helpTip = 'Press Enter to Run'; 101 | ok.onClick = startAction; 102 | ok.active = true; 103 | 104 | function startAction() { 105 | var __arts = []; 106 | 107 | __arts = getCustomNumbers((customArtboardsRadio.value ? customArts.text : ('1-' + activeDocument.artboards.length)), activeDocument.artboards); 108 | 109 | createRectangleOnArtboard(__arts); 110 | 111 | win.close(); 112 | } 113 | 114 | selection = null; 115 | function saveSettings() { 116 | var $file = new File(settingFile.folder + settingFile.name), 117 | data = [ 118 | allArtboardsRadio.value, 119 | customArtboardsRadio.value 120 | ].toString() + '\n' + customArts.text; 121 | $file.open('w'); 122 | $file.write(data); 123 | $file.close(); 124 | } 125 | function loadSettings() { 126 | var $file = File(settingFile.folder + settingFile.name); 127 | if ($file.exists) { 128 | try { 129 | $file.open('r'); 130 | var data = $file.read().split('\n'), 131 | $main = data[0].split(','), 132 | $arts = data[1]; 133 | allArtboardsRadio.value = ($main[0] === 'true'); 134 | customArtboardsRadio.value = ($main[1] === 'true'); 135 | 136 | customArts.text = $arts; 137 | customArts.enabled = customArtboardsRadio.value; 138 | } catch (e) {} 139 | $file.close(); 140 | } 141 | } 142 | 143 | function checkSettingFolder() { 144 | var $folder = new Folder(settingFile.folder); 145 | if (!$folder.exists) $folder.create(); 146 | } 147 | 148 | win.onClose = function () { 149 | saveSettings(); 150 | return true; 151 | } 152 | 153 | checkSettingFolder(); 154 | loadSettings(); 155 | win.center(); 156 | win.show(); 157 | 158 | } 159 | else { 160 | throw new Error('Create document!'); 161 | } -------------------------------------------------------------------------------- /artboardsRotateWithObjects.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Program version: Adobe Illustrator CS5+ 4 | Name: artboardsRotateWithObjects.jsx; 5 | 6 | Author: Alexander Ladygin, email: i@ladygin.pro 7 | Sergey Osokin, email: hi@sergosokin.ru 8 | 9 | Copyright (c) 2018 10 | www.ladyginpro.ru 11 | 12 | */ 13 | 14 | #target illustrator; 15 | app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS; 16 | 17 | var scriptName = 'ARWO', 18 | scriptVersion = '1.2'; 19 | 20 | try { 21 | if (documents.length > 0) { 22 | var doc = app.activeDocument, 23 | currArt = doc.artboards[doc.artboards.getActiveArtboardIndex()], 24 | currArtNum = doc.artboards.getActiveArtboardIndex() + 1, 25 | lockedItems = new Array(), 26 | hiddenItems = new Array(); 27 | 28 | // Create Main Window 29 | var dlg = new Window('dialog', scriptName + ' ver.' + scriptVersion + ' \u00A9 www.ladyginpro.ru', undefined); 30 | dlg.orientation = 'column'; 31 | dlg.alignChildren = ['fill', 'fill']; 32 | 33 | // Target radiobutton 34 | var slctTarget = dlg.add('panel', undefined, 'What to rotate?'); 35 | slctTarget.orientation = 'column'; 36 | slctTarget.alignChildren = 'left'; 37 | slctTarget.margins = 20; 38 | var currArtRadio = slctTarget.add('radiobutton', undefined, 'Active Artboard #' + currArtNum), 39 | allArtRadio = slctTarget.add('radiobutton', undefined, 'All ' + doc.artboards.length + ' Artboards'); 40 | currArtRadio.value = true; 41 | 42 | // Angle radiobutton 43 | var slctAngle = dlg.add('panel', undefined, 'Rotation angle:'); 44 | slctAngle.orientation = 'row'; 45 | slctAngle.alignChildren = ['fill', 'fill']; 46 | slctAngle.margins = 20; 47 | var cwAngle = slctAngle.add('radiobutton', undefined, '90 CW'), 48 | ccwAngle = slctAngle.add('radiobutton', undefined, '90 CCW'); 49 | cwAngle.value = true; 50 | 51 | // Buttons 52 | var btns = dlg.add('group'); 53 | btns.alignChildren = ['fill', 'fill']; 54 | btns.margins = [0, 10, 0, 0]; 55 | var cancel = btns.add('button', undefined, 'Cancel', {name: 'cancel'}); 56 | cancel.helpTip = 'Press Esc to Close'; 57 | cancel.onClick = function () { dlg.close(); } 58 | var ok = btns.add('button', undefined, 'OK', {name: 'ok'}); 59 | ok.helpTip = 'Press Enter to Run'; 60 | ok.active = true; 61 | ok.onClick = okClick; 62 | 63 | selection = null; 64 | app.redraw(); 65 | 66 | dlg.center(); 67 | dlg.show(); 68 | 69 | //Start 70 | function okClick() { 71 | // Saving information about locked & hidden pageItems 72 | saveItemsState(); 73 | // Rotate active artboard or all artboards in document 74 | if (currArtRadio.value == true) { 75 | rotateArt(currArt); 76 | } else { 77 | for (var i = 0; i < doc.artboards.length; i++) { 78 | doc.artboards.setActiveArtboardIndex(i); 79 | rotateArt(doc.artboards[i]); 80 | } 81 | } 82 | // Restoring locked & hidden pageItems 83 | restoreItemsState(); 84 | dlg.close(); 85 | } 86 | } else { 87 | throw new Error(scriptName + '\nPlease open a document before running this script.'); 88 | } 89 | } catch (e) { 90 | showError(e); 91 | } 92 | 93 | // Save information about locked & hidden pageItems 94 | function saveItemsState() { 95 | for (var i = 0; i < doc.pageItems.length; i++) { 96 | var currItem = doc.pageItems[i]; 97 | if (currItem.locked == true) { 98 | lockedItems.push(i); 99 | currItem.locked = false; 100 | } 101 | if (currItem.hidden == true) { 102 | hiddenItems.push(i); 103 | currItem.hidden = false; 104 | } 105 | } 106 | } 107 | 108 | // Restoring locked & hidden pageItems 109 | function restoreItemsState() { 110 | for (var i = 0; i < lockedItems.length; i++) { 111 | var index = lockedItems[i]; 112 | doc.pageItems[index].locked = true; 113 | } 114 | for (var j = 0; j < hiddenItems.length; j++) { 115 | var index = hiddenItems[j]; 116 | doc.pageItems[index].hidden = true; 117 | } 118 | } 119 | 120 | // Main function for rotate artboard 121 | function rotateArt(board) { 122 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM; 123 | 124 | var artRect = [].concat(board.artboardRect), 125 | artWidth = artRect[2] - artRect[0], 126 | artHeight = -(artRect[3] - artRect[1]); 127 | deselect(); 128 | doc.selectObjectsOnActiveArtboard(); 129 | 130 | // Rotate artboard 131 | var newArtRect = [ 132 | artRect[0] + artWidth / 2 - (artHeight / 2), 133 | artRect[1] - artHeight / 2 + (artWidth / 2), 134 | artRect[2] - artWidth / 2 + (artHeight / 2), 135 | artRect[3] + artHeight / 2 - (artWidth / 2) 136 | ]; 137 | 138 | // Rotate objects 139 | for (var k = 0; k < selection.length; k++) { 140 | var bnds = selection[k].position, 141 | __width = selection[k].width, 142 | __height = selection[k].height, 143 | top = bnds[1] - artRect[1], 144 | left = bnds[0] - artRect[0]; 145 | 146 | if (cwAngle.value == true) { 147 | // rotate 90 CW 148 | selection[k].rotate(-90, true, true, true, true, Transformation.CENTER); 149 | selection[k].position = [newArtRect[2] - __height + top, newArtRect[1] - left]; 150 | } else { 151 | // rotate 90 CCW 152 | selection[k].rotate(90, true, true, true, true, Transformation.CENTER); 153 | selection[k].position = [newArtRect[0] - top, newArtRect[3] + left + __width]; 154 | } 155 | } 156 | deselect(); 157 | 158 | board.artboardRect = newArtRect; 159 | } 160 | 161 | function deselect() { 162 | selection = null; 163 | } 164 | 165 | function showError(err) { 166 | if (confirm(scriptName + ': an unknown error has occurred.\n' + 167 | 'Would you like to see more information?', true, 'Unknown Error')) { 168 | alert(err + ': on line ' + err.line, 'Script Error', true); 169 | } 170 | } -------------------------------------------------------------------------------- /batchTextEdit.jsx: -------------------------------------------------------------------------------- 1 | // batchTextEdit.jsx 2 | // adobe Illustrator CSx script 3 | // for editing the contents of the text frames all together. 4 | // 5 | // Usage: 6 | // 1. Select the textframe(s) and run this script. 7 | // 2. Edit the contents in the dialog. Then hit OK button. 8 | // 9 | // Notice: 10 | // * The attribute of the first character is applied to whole 11 | // contents of textframe if you run this script for it. 12 | // It is assumed that each contents is plain text. 13 | // 14 | // * For the multiline contents, the return code characters are 15 | // replaced to the alternative ones (default:"@/") in the dialog. 16 | // When applying the edited contents, they are replaced to 17 | // the return code. This means you can't use "@/" itself in the 18 | // contents. You can change it in the setting part of the script. 19 | // 20 | // * The order of the texts in the dialog depends on the rectangle 21 | // area surrounding each top-left corner of the selected textframes. 22 | // If the width of the area is greater than the height of it, the 23 | // order is from left to right. Otherwise from top to bottom. 24 | 25 | // test env: Adobe Illustrator CS3, CS6 (Windows) 26 | 27 | // Copyright(c) 2013 Hiroyuki Sato 28 | // https://github.com/shspage 29 | // This script is distributed under the MIT License. 30 | // See the LICENSE file for details. 31 | 32 | // Sorting options by Alexander Ladygin 33 | 34 | main(); 35 | 36 | function main() { 37 | // - settings ------------- 38 | // return code alternative character(s) used while editting 39 | const return_code_alt = "@/"; 40 | 41 | // return code that used in regexp (escape the characters if it needs) 42 | const return_code_alt_for_rex = return_code_alt; 43 | 44 | // edittext size 45 | const edittext_width = 200; 46 | const edittext_height = 200; 47 | 48 | // - settings end ------------- 49 | // ---------------------------- 50 | if (app.documents.length < 1) return; 51 | 52 | // show a dialog 53 | var win = new Window("dialog", "batchTextEdit"); 54 | 55 | // add edittext 56 | var et_opt = { 57 | multiline: true, 58 | scrolling: true 59 | }; 60 | var ver16 = (app.version.substr(0, 2) > "15"); 61 | if (ver16) et_opt.wantReturn = true; 62 | 63 | var et = win.add("edittext", [0, 0, edittext_width, edittext_height], "", et_opt); 64 | var sortByTree = win.add('checkbox', [0, 0, edittext_width, 30], 'Sort by [Layers] tree\ninstead of visual order'), 65 | sortReverse = win.add('checkbox', [0, 0, edittext_width, 15], 'Reverse display order'); 66 | 67 | // get textframes in the selection 68 | var tfs = [], tfsSort = [], tfsOriginal = []; // textframes 69 | extractTextFramesAsVTextFrameItem(app.activeDocument.selection, tfs, tfsOriginal, tfsSort); 70 | if (tfs.length < 1) { 71 | alert("Please select textframes"); 72 | return; 73 | } 74 | 75 | // sort tfs 76 | sortVTextFramesReasonableByPosition(tfs); 77 | 78 | // get the contents of tfs 79 | var conts = []; 80 | function getConts() { 81 | conts = []; 82 | var rex_return_code = new RegExp("\r", "g"); 83 | for (var i = 0; i < tfs.length; i++) { 84 | conts.push(tfs[i].tf.contents.replace( 85 | rex_return_code, return_code_alt)); 86 | } 87 | } 88 | 89 | getConts(); 90 | 91 | sortReverse.onClick = function () { 92 | tfs.reverse(); 93 | getConts(); 94 | et.text = conts.join("\n"); 95 | win.update(); 96 | }; 97 | sortByTree.onClick = sortCheckboxes; 98 | 99 | function sortCheckboxes (__reverse) { 100 | if (sortByTree.value) tfs = tfsOriginal; 101 | else tfs = tfsSort; 102 | 103 | sortVTextFramesReasonableByPosition(tfs); 104 | if (sortReverse.value) tfs.reverse(); 105 | getConts(); 106 | et.text = conts.join("\n"); 107 | win.update(); 108 | } 109 | 110 | et.text = conts.join("\n"); 111 | et.active = true; 112 | 113 | // add statictext 114 | var st_text = "* \"" + return_code_alt + "\" means a return code" 115 | if (!ver16) st_text += "\r* Use ctrl+enter for new line" 116 | win.add("statictext", undefined, st_text, { 117 | multiline: true 118 | }); 119 | 120 | 121 | // add buttons 122 | var gr = win.add("group"); 123 | var btn_ok = gr.add("button", undefined, "OK"); 124 | var btn_cancel = gr.add("button", undefined, "Cancel"); 125 | btn_ok.onClick = function() { 126 | replaceContents(tfs, et.text.split("\n"), 127 | new RegExp(return_code_alt_for_rex, "g")); 128 | win.close() 129 | }; 130 | 131 | win.show(); 132 | // -------------------------------------------------- 133 | function vTextFrameItem(tf) { 134 | // virtual textframe for comparing the each position 135 | this.tf = tf; 136 | if (tf.kind == TextType.POINTTEXT) { 137 | this.left = tf.left; 138 | this.top = tf.top; 139 | } else { 140 | var tp = tf.textPath; 141 | this.left = tp.left; 142 | this.top = tp.top; 143 | } 144 | } 145 | // -------------------------------------------------- 146 | function replaceContents(tfs, et_texts, rex_return_code_alt) { 147 | while (et_texts[et_texts.length - 1 ] == "") et_texts.pop(); 148 | 149 | for (var i = 0; i < tfs.length; i++) { 150 | if (i >= et_texts.length) break; 151 | 152 | tfs[i].tf.contents = et_texts[i].replace(rex_return_code_alt, "\r"); 153 | } 154 | } 155 | // -------------------------------------------------- 156 | function sortVTextFramesReasonableByPosition(tfs) { 157 | if (!sortByTree.value) { 158 | var rect = []; 159 | // reft, top, right, bottom 160 | getVTextFramesRect(tfs, rect); 161 | 162 | if (rect[1] - rect[3] < rect[2] - rect[0]) { // height < width 163 | // left -> right || top -> bottom 164 | tfs.sort(function(a, b) { 165 | return a.left == b.left ? 166 | b.top - a.top : 167 | a.left - b.left 168 | }); 169 | } else { 170 | // top -> down || left -> right 171 | tfs.sort(function(a, b) { 172 | return a.top == b.top ? 173 | a.left - b.left : 174 | b.top - a.top 175 | }); 176 | } 177 | } 178 | } 179 | // -------------------------------------------------- 180 | function getVTextFramesRect(tfs, rect) { 181 | // get the rect that includes each top-left corner of tfs 182 | var top, left; 183 | 184 | for (var i = 0; i < tfs.length; i++) { 185 | top = tfs[i].top; 186 | left = tfs[i].left; 187 | 188 | if (i == 0) { 189 | // reft, top, right, bottom 190 | rect.push(left); 191 | rect.push(top); 192 | rect.push(left); 193 | rect.push(top); 194 | } else { 195 | rect[0] = Math.min(rect[0], left); 196 | rect[1] = Math.max(rect[1], top); 197 | rect[2] = Math.max(rect[2], left); 198 | rect[3] = Math.min(rect[3], top); 199 | } 200 | } 201 | } 202 | // -------------------------------------------------- 203 | function extractTextFramesAsVTextFrameItem(s, r, _r, __r) { 204 | // s is an array of pageitems ( ex. selection ) 205 | for (var i = 0; i < s.length; i++) { 206 | if (s[i].typename === "TextFrame") { 207 | r.push(new vTextFrameItem(s[i])); 208 | _r.push(new vTextFrameItem(s[i])); 209 | __r.push(new vTextFrameItem(s[i])); 210 | } else if (s[i].typename == "GroupItem") { 211 | extractTextFramesAsVTextFrameItem(s[i].pageItems, r, _r, __r); 212 | } 213 | } 214 | } 215 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Illustrator-script www.ladygin.pro](https://dl.dropboxusercontent.com/s/bchln1y7s3r6lqb/illustrator-scripts-github-poster.jpg?dl=0) 2 | # illustrator-scripts 3 | ## Collection of scripts for adobe illustrator, created or modified by me. 4 | ### **How install:** 5 | 1. Download archive and unzip. All scripts are in the folder jsx 6 | 2. Place .jsx in the Illustrator Scripts folder: 7 | OS X: /Applications/Adobe Illustrator [vers.]/Presets.localized/en_GB/Scripts 8 | Windows (32 bit): C:\Program Files (x86)\Adobe\Adobe Illustrator [vers.]\Presets\en_GB [or your localization]\Scripts\ 9 | Windows (64 bit): C:\Program Files\Adobe\Adobe Illustrator [vers.] (64 Bit)\Presets\en_GB [or your localization]\Scripts\ 10 | 3. Restart Illustrator 11 | 12 | 13 | ## **ArtboardResizeWithObjects** 14 | Script to resize on value an document artboards with all the objects on it. 15 | #### Usage: 16 | 1. Open your file 17 | 2. Run script File → Scripts → artboardResizeWithObjects.jsx 18 | 3. Select the size of the artboard or a percentage of the size, also configure other items 19 | 3. Press button "OK" or press enter 20 | 21 | ![ArtboardResizeWithObjects](https://dl.dropboxusercontent.com/s/et8r3kql8yxw2yx/artboardResizeWithObjects.gif?dl=0) 22 | 23 | 24 | ## **ArtboardsRotateWithObjects** 25 | Script to rotate 90 degrees an document artboards with all the objects on it. 26 | Author: Alexander Ladygin. UI: [Sergey Osokin](https://github.com/creold/). 27 | #### Usage: 28 | 1. Open your file 29 | 2. Run script File → Scripts → artboardsRotateWithObjects.jsx 30 | 3. Press button "OK" or press enter 31 | 32 | ![ArtboardsRotateWithObjects](https://dl.dropboxusercontent.com/s/kxwaxk6am5hddy9/artboardsRotateWithObjects.gif?dl=0) 33 | 34 | 35 | ## **Harmonizer** 36 | Sort a lot of objects in Adobe Illustrator is hard. With Harmonizer you can just achieve results with a few clicks. 37 | #### Usage: 38 | 1. Select objects 39 | 2. Run script File → Scripts → harmonizer.jsx 40 | 3. Set the desired settings 41 | 4. Press button "OK" or press enter 42 | 43 | ![Harmonizer](https://dl.dropboxusercontent.com/s/cyox6jo71bvj85f/harmonizer.gif?dl=0) 44 | 45 | 46 | ## **InlineSVGToAI** 47 | The script inserts the SVG code as an object from the clipboard into the Adobe Illustrator CC 2014+. Adobe Illustrator CC 2018 v.22.1 (march, 2018) can insert SVG graphics without a script. 48 | Author: Alexander Ladygin. Code refactoring: [Sergey Osokin](https://github.com/creold/). 49 | 50 | ![InlineSVGToAI](https://dl.dropboxusercontent.com/s/flsk054h1vk2qdf/inlineSVGToAI.gif?dl=0) 51 | 52 | 53 | ## **Cropulka** 54 | The script cuts all that goes beyond the artboard. This script is ideal for microstock and printing, well, or just you need to trim the elements on the artboard. 55 | #### Usage: 56 | 1. Run script File → Scripts → cropulka.jsx 57 | 2. Select the desired settings 58 | - The script also cuts the images and the mesh, although the mesh will be rasterized and the picture will lose its connection. Also all raster effects will be separate images. 59 | 3. Press button "OK" or press enter 60 | 61 | ![Cropulka](https://dl.dropboxusercontent.com/s/1g88o9rzo34glrn/cropulka.gif?dl=0) 62 | 63 | 64 | ## **Fillinger** 65 | A Jongware Script - modified by Alexander Ladygin. The script fills the object with other objects in a random order or with one object. The ability to select the rotation of the object and much more. 66 | #### Usage: 67 | 1. Select objects 68 | 2. Run script File → Scripts → fillinger.jsx 69 | 3. Select the desired settings 70 | - The item to be filled must be either PathItem or CompoundPathItem, the items to be filled can be either in the group or outside the group. 71 | 4. Press button "OK" or press enter 72 | 73 | ![Fillinger](https://dl.dropboxusercontent.com/s/1cacp1azneso5ib/fillinger.gif?dl=0) 74 | 75 | 76 | ## **Randomus** 77 | The script can: 78 | - Random fill color 79 | - Random stroke color 80 | - Random scale 81 | - Random rotate 82 | - Random opacity 83 | - Random position X, Y 84 | #### Usage: 85 | 1. Select objects 86 | 2. Run script File → Scripts → randomus.jsx 87 | 3. Press buttons - result in real time 88 | 4. Press "OK" or press enter - confirm changes, or press "Cancel" or press escape - cancel changes 89 | 90 | ![Randomus](https://dl.dropboxusercontent.com/s/hrooxlfcor2afsn/randomus.gif?dl=0) 91 | 92 | 93 | ## **ReplaceItems** 94 | Script for replacing objects with objects, the top object, an object from the clipboard. It can rotate elements in random order, copy width and height, and much more. 95 | #### Usage: 96 | 1. Select objects 97 | 2. Select the desired settings 98 | - You can copy an object to the clipboard and use it as an object to insert. 99 | 3. Run script File → Scripts → replaceItems.jsx 100 | 4. Press "OK" or press enter 101 | 102 | ![ReplaceItems](https://dl.dropboxusercontent.com/s/ajl65b4atapa1q2/replaceItems.gif?dl=0) 103 | 104 | 105 | ## **PuzzleClipper** 106 | The script makes copies of the last (lowest) object and puts them into a mask based on other (upper) objects. Creates a puzzle. 107 | #### Usage: 108 | 1. Select objects 109 | - The last (lowest in \[Layers\]) object will be taken as the main element for the puzzle 110 | 2. Select the desired settings 111 | - You can copy an object to the clipboard and use it as an object to insert. 112 | 3. Run script File → Scripts → puzzleClipper.jsx 113 | 4. Press "OK" or press enter 114 | 115 | ![PuzzleClipper](https://dl.dropboxusercontent.com/s/gmqafobwmhypzf4/puzzleClipper.gif?dl=0) 116 | 117 | 118 | ## **ArtboardItemsMoveToNewLayer** 119 | The script places all objects on the artboard in a new layer. 120 | #### Usage: 121 | 1. Run script File → Scripts → artboardItemsMoveToNewLayer.jsx 122 | 2. Select the desired artboards 123 | - If custom is selected, you can specify the numbers of the artboard as pages when printing, for example: 1, 2, 5-8 124 | 3. Press button "OK" or press enter 125 | 126 | ![ArtboardItemsMoveToNewLayer](https://dl.dropboxusercontent.com/s/fdvz551f7esk2wq/artboardItemsMoveToNewLayer.gif?dl=0) 127 | 128 | 129 | ## **CreateArtboardsFromTheSelection** 130 | The script creates artboards on selected items 131 | #### Usage: 132 | 1. Select objects 133 | 2. Run script File → Scripts → createArtboardsFromTheSelection.jsx 134 | 3. Set the desired settings 135 | 4. Press button "OK" or press enter 136 | 137 | ![CreateArtboardsFromTheSelection](https://dl.dropboxusercontent.com/s/yx0rm5z7767fvt2/createArtboardFromTheSelection.gif?dl=0) 138 | 139 | 140 | ## **ForceCloseOtherDocuments** 141 | The script closes the documents except the active one, it closes them without saving. It happens that you open many documents and various auxiliary elements, and to close them you need time, which you are wasting, the script will help you save time. 142 | #### Usage: 143 | 1. Select objects 144 | 2. Select the desired settings 145 | - You can copy an object to the clipboard and use it as an object to insert. 146 | 3. Run script File → Scripts → forceCloseOtherDocuments.jsx 147 | 4. Press "OK" or press enter 148 | 149 | ![ForceCloseOtherDocuments](https://dl.dropboxusercontent.com/s/sg9qq2hlki7pff9/forceCloseOtherDocuments.gif?dl=0) 150 | 151 | 152 | ## **BatchTextEdit** 153 | Script for editing the contents of the text frames all together. 154 | Author: [Hiroyuki Sato](https://github.com/shspage). Modify (sort by [Layers] and reverse): Alexander Ladygin 155 | #### Usage: 156 | 1. Select the textframe(s). 157 | 2. Run script File → Scripts → batchTextEdit.jsx 158 | 3. Edit the contents in the dialog. 159 | 4. Press "OK" or press enter 160 | 161 | 162 | ## **CompoundFix** 163 | Script to fix the bug in compoundPathItems. In compoundPathItem there can be a group, because of which there are all sorts of problems, this script will help to fix this bug. 164 | #### Usage: 165 | 1. Select items (optional). 166 | 2. Run script File → Scripts → compoundFix.jsx 167 | 3. Select - fix all or selected. 168 | 4. Press "OK" or press enter 169 | 170 | 171 | ## **TransferSwatches** 172 | The script copies color samples from the document to the active document while maintaining the hierarchy. 173 | #### Usage: 174 | 1. Run script File → Scripts → transferSwatches.jsx 175 | 2. Select the document from which to copy the swatches 176 | 3. Press "OK" or press enter 177 | 178 | ![TransferSwatches](https://dl.dropboxusercontent.com/s/51ert15kcp7ufm7/transferSwatches.gif?dl=0) 179 | 180 | ##   181 | ## **Contact** 182 | Email: [i@ladygin.pro](mailto:i@ladygin.pro)
183 | Site: [www.ladyginpro.ru](http://ladyginpro.ru) 184 | 185 | ## **LICENSE** 186 | All scripts is licensed under the MIT licence.
187 | See the included LICENSE file for more details. -------------------------------------------------------------------------------- /artboardItemsMoveToNewLayer.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Program version: Adobe Illustrator CS5+ 4 | Name: artboardItemsMoveToNewLayer.jsx; 5 | 6 | Author: Alexander Ladygin, email: i@ladygin.pro 7 | 8 | Copyright (c) 2018 9 | www.ladyginpro.ru 10 | 11 | */ 12 | Object.prototype.removeItemsWithArray = function (items) {var obj = [];for (var i = 0; i < this.length; i++) {if (!check(this[i])) {obj.push(this[i]);}}function check(e) {for (var j = 0; j < items.length; j++) {if (e === items[j]) {return true;}}return false;}return obj;}; 13 | Object.prototype.emptyLayers = function () {var arr = [];function check(layers) {var obj = [];for (var i = 0; i < layers.length; i++) {if (!layers[i].layers.length && !layers[i].pageItems.length) { obj.push(layers[i]); continue;} var subLayers = layers[i].subLayers(),emptySubLayers = layers[i].emptySubLayers(),count = subLayers.removeItemsWithArray(emptySubLayers).length;if (!count && !layers[i].pageItems.length) {obj = obj.concat(layers[i]);}}return obj;}var doc = this;for (var i = 0; i < doc.length; i++) {arr = arr.concat(check(doc[i].layers));}return arr;}; 14 | Object.prototype.subLayers = function (level) {var arr = [], count = 0;if (level !== undefined) {level = level - 1;}function subLayers(layer) {var obj = [], sub = layer.layers;for (var j = 0; j < sub.length; j++) {obj = obj.concat(sub[j]);if ((level === undefined) || (sub[j].layers.length > 0 && count < level)) {obj = obj.concat(subLayers(sub[j], count++));count--;}}return obj;}var obj = this;for (var j = 0; j < obj.length; j++) {arr = arr.concat(subLayers(obj[j]));}return arr;}; 15 | Object.prototype.emptySubLayers = function (level) {var arr = [], obj = this;function process(sub) {var sub_arr = [];sub = sub.subLayers(level).reverse();for (var i = 0; i < sub.length; i++) {if (sub[i].pageItems.length > 0) {var parents = sub[i].pageItems[0].getAllParents();parents.pop();sub_arr = sub_arr.concat(parents);}}return sub.removeItemsWithArray(sub_arr).reverse();}for (var i = 0; i < obj.length; i++) {arr = arr.concat(process(obj[i]));}return arr;}; 16 | Array.prototype.remove = function(){var i = this.length; if (i > 0) while (i--) this[i].remove();} 17 | 18 | var scriptName = 'AIMTNL', 19 | copyright = ' \u00A9 www.ladyginpro.ru', 20 | settingFile = { 21 | name: scriptName + '__setting.json', 22 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 23 | }; 24 | 25 | if (app.documents.length) { 26 | function getCustomNumbers ($str, items, returnItems) { 27 | var __num = $str.replace(/ /g, '').replace(/[^-0-9^,]/gim,'').split(','), 28 | $maxItems = items.length, 29 | l = __num.length, 30 | arr = []; 31 | 32 | function getNumbersBetweenMinMax (min, max) { 33 | var numbers = []; 34 | for (var n = min; n <= max; n++) { 35 | if (n < $maxItems) { 36 | numbers.push(returnItems ? items[n] : n); 37 | } 38 | } 39 | return numbers; 40 | } 41 | 42 | for (var j = 0; j < l; j++) { 43 | if (__num[j].indexOf('-') > -1) { 44 | var values = __num[j].split('-'), 45 | min = parseInt(values[0]), 46 | max = parseInt(values[1]); 47 | 48 | if (!isNaN(min) && !isNaN(max)) arr = arr.concat(getNumbersBetweenMinMax(min - 1, max - 1)); 49 | } 50 | else { 51 | var __val = parseInt(__num[j]); 52 | if (!isNaN(__val) && __val <= $maxItems) { 53 | arr.push(returnItems ? items[__val - 1] : __val - 1); 54 | } 55 | } 56 | } 57 | 58 | return arr; 59 | } 60 | 61 | 62 | function __artboardItemsMoveToNewLayer (__artNumbers) { 63 | var arts = activeDocument.artboards, 64 | l = __artNumbers.length; 65 | 66 | selection = null; 67 | 68 | function __move (items, __index) { 69 | var layer = activeDocument.layers.add(), 70 | j = items.length; 71 | 72 | if (layerNameCheckbox.value) layer.name = arts[__index].name; 73 | 74 | if (j > 0) while (j--) { 75 | items[j].moveToBeginning(layer); 76 | } 77 | } 78 | 79 | for (var i = 0; i < l; i++) { 80 | activeDocument.artboards.setActiveArtboardIndex(__artNumbers[i]); 81 | activeDocument.selectObjectsOnActiveArtboard(); 82 | __move(selection, __artNumbers[i]); 83 | selection = null; 84 | } 85 | } 86 | 87 | var selectionBak = selection; 88 | 89 | var win = new Window('dialog', 'Artboards items move to new layer \u00A9 www.ladyginpro.ru', undefined); 90 | win.orientation = 'column'; 91 | win.alignChildren = ['fill', 'fill']; 92 | 93 | var panel = win.add('panel', undefined, 'Artboards:'); 94 | panel.orientation = 'column'; 95 | panel.alignChildren = ['fill', 'fill']; 96 | panel.margins = 20; 97 | 98 | var groupRadio = panel.add('group'); 99 | groupRadio.orientation = 'row'; 100 | 101 | var allArtboardsRadio = groupRadio.add('radiobutton', undefined, 'All'), 102 | customArtboardsRadio = groupRadio.add('radiobutton', undefined, 'Custom'); 103 | allArtboardsRadio.value = true; 104 | allArtboardsRadio.onClick = function () { customArts.enabled = false; }; 105 | customArtboardsRadio.onClick = function () { customArts.enabled = true; }; 106 | 107 | var customArts = panel.add('edittext', undefined, activeDocument.artboards.getActiveArtboardIndex() + 1); 108 | customArts.enabled = false; 109 | 110 | var panelCheckbox = win.add('panel'); 111 | panelCheckbox.orientation = 'column'; 112 | panelCheckbox.alignChildren = ['fill', 'fill']; 113 | panelCheckbox.margins = 10; 114 | 115 | var removeEmptyLayersCheckbox = panelCheckbox.add('checkbox', undefined, 'Clear empty layers & sub layers'), 116 | layerNameCheckbox = panelCheckbox.add('checkbox', undefined, 'Layer name from the artboard name'); 117 | 118 | var winButtons = win.add('group'); 119 | winButtons.orientation = 'row'; 120 | winButtons.alignChildren = ['fill', 'fill']; 121 | 122 | var cancel = winButtons.add('button', undefined, 'Cancel'); 123 | cancel.helpTip = 'Press Esc to Close'; 124 | cancel.onClick = function () { win.close(); } 125 | 126 | var ok = winButtons.add('button', undefined, 'OK'); 127 | ok.helpTip = 'Press Enter to Run'; 128 | ok.onClick = startAction; 129 | ok.active = true; 130 | 131 | function startAction() { 132 | var __arts = []; 133 | 134 | __arts = getCustomNumbers((customArtboardsRadio.value ? customArts.text : ('1-' + activeDocument.artboards.length)), activeDocument.artboards); 135 | 136 | __artboardItemsMoveToNewLayer(__arts); 137 | 138 | if (removeEmptyLayersCheckbox.value) [activeDocument].emptyLayers().remove(); 139 | // selection = selectionBak; 140 | 141 | win.close(); 142 | } 143 | 144 | selection = null; 145 | function saveSettings() { 146 | var $file = new File(settingFile.folder + settingFile.name), 147 | data = [ 148 | allArtboardsRadio.value, 149 | customArtboardsRadio.value, 150 | removeEmptyLayersCheckbox.value, 151 | layerNameCheckbox.value 152 | ].toString() + '\n' + customArts.text; 153 | $file.open('w'); 154 | $file.write(data); 155 | $file.close(); 156 | } 157 | function loadSettings() { 158 | var $file = File(settingFile.folder + settingFile.name); 159 | if ($file.exists) { 160 | try { 161 | $file.open('r'); 162 | var data = $file.read().split('\n'), 163 | $main = data[0].split(','), 164 | $arts = data[1]; 165 | allArtboardsRadio.value = ($main[0] === 'true'); 166 | customArtboardsRadio.value = ($main[1] === 'true'); 167 | removeEmptyLayersCheckbox.value = ($main[2] === 'true'); 168 | layerNameCheckbox.value = ($main[3] === 'true'); 169 | 170 | customArts.text = $arts; 171 | customArts.enabled = customArtboardsRadio.value; 172 | } catch (e) {} 173 | $file.close(); 174 | } 175 | } 176 | 177 | function checkSettingFolder() { 178 | var $folder = new Folder(settingFile.folder); 179 | if (!$folder.exists) $folder.create(); 180 | } 181 | 182 | win.onClose = function () { 183 | saveSettings(); 184 | return true; 185 | } 186 | 187 | checkSettingFolder(); 188 | loadSettings(); 189 | win.center(); 190 | win.show(); 191 | 192 | } 193 | else { 194 | throw new Error('Create document!'); 195 | } -------------------------------------------------------------------------------- /random-dash.jsx: -------------------------------------------------------------------------------- 1 | #target illustrator 2 | 3 | var preview = { 4 | value: false 5 | }, 6 | isUndo = false; 7 | 8 | 9 | function randomDash (userOptions) { 10 | var values = userOptions || { 11 | mindash: 2, 12 | maxdash: 20, 13 | mingap: 2, 14 | maxgap: 10, 15 | minStroke: 1, 16 | maxStroke: 3 17 | }; 18 | 19 | for (var i = 0; i < activeDocument.selection.length; i++) { 20 | var dash = []; 21 | for (var j = 0; j < 6; j += 2) { 22 | dash[j] = Math.random() * (values.maxdash - values.mindash) + values.mindash; 23 | dash[j + 1] = Math.random() * (values.maxgap - values.mingap) + values.mingap; 24 | } 25 | activeDocument.selection[i].strokeDashes = dash; 26 | activeDocument.selection[i].strokeWidth = values.minStroke + Math.random() * (values.maxStroke - values.minStroke); 27 | } 28 | } 29 | 30 | 31 | 32 | function inputNumberEvents (ev, _input, min, max, callback){ 33 | var step, 34 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 35 | _value = parseFloat(_input.text), 36 | units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 37 | 38 | min = (min === undefined ? 0 : min); 39 | max = (max === undefined ? Infinity : max); 40 | step = (ev.shiftKey ? 10 : (ev.ctrlKey ? .1 : 1)); 41 | 42 | if (isNaN(_value)) { 43 | _input.text = min; 44 | } 45 | else { 46 | _value = ( (_dir === 'u') ? _value + step : ((_dir === 'd') ? _value - step : false) ); 47 | if (_value !== false) { 48 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 49 | _input.text = _value; 50 | if (callback instanceof Function) callback(_value, _input, min, max, units); 51 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 52 | } 53 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 54 | } 55 | } 56 | 57 | 58 | win = new Window('dialog', 'Random dash \u00A9 UI (Alexander ladygin)'); 59 | 60 | win.alignChildren = 'fill'; 61 | 62 | with (win.add('panel', undefined, 'Dash:')) { 63 | alignChildren = ['fill', 'bottom']; 64 | 65 | with(add('group')) { 66 | with(add('group')) { 67 | var __minDashText = add('statictext', undefined, 'Min'), 68 | __minDashInput = add('edittext', [0, 0, 40, 25], '2'), 69 | __minDashSlider = add('slider', [0, 0, 80, 15], 1, 2, 100); 70 | __minDashInput.text = __minDashSlider.value; 71 | 72 | __minDashSlider.onChanging = function (e) { __minDashInput.text = Math.round(this.value); } 73 | // __minDashSlider.onChange = function (e) { previewStart(); } 74 | __minDashInput.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __minDashSlider.minvalue, __minDashSlider.maxvalue); }); 75 | __minDashInput.addEventListener('keyup', function (e) { __minDashSlider.value = Math.round(this.text); }); 76 | // __minDashInput.onChange = function (e) { previewStart(); }; 77 | } 78 | with(add('group')) { 79 | var __maxDashSlider = add('slider', [0, 0, 80, 15], 20, 2, 100), 80 | __maxDashInput = add('edittext', [0, 0, 40, 25], '20'), 81 | __maxDashText = add('statictext', undefined, 'Max'); 82 | __maxDashInput.text = __maxDashSlider.value; 83 | 84 | __maxDashSlider.onChanging = function (e) { __maxDashInput.text = Math.round(this.value); } 85 | // __maxDashSlider.onChange = function (e) { previewStart(); } 86 | __maxDashInput.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __maxDashSlider.maxvalue, __maxDashSlider.maxvalue); }); 87 | __maxDashInput.addEventListener('keyup', function (e) { __maxDashSlider.value = Math.round(this.text); }); 88 | // __maxDashInput.onChange = function (e) { previewStart(); }; 89 | } 90 | } 91 | } 92 | 93 | with (win.add('panel', undefined, 'Gap:')) { 94 | alignChildren = ['fill', 'bottom']; 95 | 96 | with(add('group')) { 97 | with(add('group')) { 98 | var __minGapText = add('statictext', undefined, 'Min'), 99 | __minGapInput = add('edittext', [0, 0, 40, 25], '1'), 100 | __minGapSlider = add('slider', [0, 0, 80, 15], 1, 1, 100); 101 | __minGapInput.text = __minGapSlider.value; 102 | 103 | __minGapSlider.onChanging = function (e) { __minGapInput.text = Math.round(this.value); } 104 | // __minGapSlider.onChange = function (e) { previewStart(); } 105 | __minGapInput.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __minGapSlider.minvalue, __minGapSlider.maxvalue); }); 106 | __minGapInput.addEventListener('keyup', function (e) { __minGapSlider.value = Math.round(this.text); }); 107 | // __minGapInput.onChange = function (e) { previewStart(); }; 108 | } 109 | with(add('group')) { 110 | var __maxGapSlider = add('slider', [0, 0, 80, 15], 10, 2, 100), 111 | __maxGapInput = add('edittext', [0, 0, 40, 25], '10'), 112 | __maxGapText = add('statictext', undefined, 'Max'); 113 | __maxGapInput.text = __maxGapSlider.value; 114 | 115 | __maxGapSlider.onChanging = function (e) { __maxGapInput.text = Math.round(this.value); } 116 | // __maxGapSlider.onChange = function (e) { previewStart(); } 117 | __maxGapInput.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __maxGapSlider.maxvalue, __maxGapSlider.maxvalue); }); 118 | __maxGapInput.addEventListener('keyup', function (e) { __maxGapSlider.value = Math.round(this.text); }); 119 | // __maxGapInput.onChange = function (e) { previewStart(); }; 120 | } 121 | } 122 | } 123 | 124 | with (win.add('panel', undefined, 'Stroke:')) { 125 | alignChildren = ['fill', 'bottom']; 126 | 127 | with(add('group')) { 128 | with(add('group')) { 129 | var __minStrokeText = add('statictext', undefined, 'Min'), 130 | __minStrokeInput = add('edittext', [0, 0, 40, 25], '1'), 131 | __minStrokeSlider = add('slider', [0, 0, 80, 15], 1, 1, 100); 132 | __minStrokeInput.text = __minStrokeSlider.value; 133 | 134 | __minStrokeSlider.onChanging = function (e) { __minStrokeInput.text = Math.round(this.value); } 135 | // __minStrokeSlider.onChange = function (e) { previewStart(); } 136 | __minStrokeInput.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __minStrokeSlider.minvalue, __minStrokeSlider.maxvalue); }); 137 | __minStrokeInput.addEventListener('keyup', function (e) { __minStrokeSlider.value = Math.round(this.text); }); 138 | // __minStrokeInput.onChange = function (e) { previewStart(); }; 139 | } 140 | with(add('group')) { 141 | var __maxStrokeSlider = add('slider', [0, 0, 80, 15], 3, 2, 100), 142 | __maxStrokeInput = add('edittext', [0, 0, 40, 25], '3'), 143 | __maxStrokeText = add('statictext', undefined, 'Max'); 144 | __maxStrokeInput.text = __maxStrokeSlider.value; 145 | 146 | __maxStrokeSlider.onChanging = function (e) { __maxStrokeInput.text = Math.round(this.value); } 147 | // __maxStrokeSlider.onChange = function (e) { previewStart(); } 148 | __maxStrokeInput.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __maxStrokeSlider.maxvalue, __maxStrokeSlider.maxvalue); }); 149 | __maxStrokeInput.addEventListener('keyup', function (e) { __maxStrokeSlider.value = Math.round(this.text); }); 150 | // __maxStrokeInput.onChange = function (e) { previewStart(); }; 151 | } 152 | } 153 | } 154 | 155 | with (win.add('group')) { 156 | orientation = 'row'; 157 | alignChildren = ['fill', 'fill']; 158 | 159 | var previewBtn = add('button', undefined, 'Preview'), 160 | cancelBtn = add('button', undefined, 'Cancel'), 161 | applyBtn = add('button', undefined, 'Ok', { name: 'ok' }); 162 | 163 | previewBtn.onClick = function() { preview.value = true; previewStart(); } 164 | cancelBtn.onClick = function() { win.close(); } 165 | applyBtn.onClick = function() { 166 | if (preview.value && isUndo) { 167 | isUndo = false; 168 | win.close(); 169 | } 170 | else { 171 | app.undo(); 172 | startAction(); 173 | isUndo = false; 174 | win.close(); 175 | } 176 | } 177 | } 178 | 179 | // } 180 | 181 | function startAction() { 182 | randomDash({ 183 | mindash: +(__minDashInput.text), 184 | maxdash: +(__maxDashInput.text), 185 | mingap: +(__minGapInput.text), 186 | maxgap: +(__maxGapInput.text), 187 | minStroke: +(__minStrokeInput.text), 188 | maxStroke: +(__maxStrokeInput.text) 189 | }); 190 | } 191 | 192 | function previewStart() { 193 | if (preview.value) { 194 | if (isUndo) app.undo(); 195 | else isUndo = true; 196 | 197 | startAction(); 198 | app.redraw(); 199 | } 200 | else if (isUndo) { 201 | app.undo(); 202 | app.redraw(); 203 | isUndo = false; 204 | } 205 | } 206 | 207 | 208 | win.onClose = function () { 209 | try { 210 | if (isUndo) { 211 | app.undo(); 212 | app.redraw(); 213 | isUndo = false; 214 | } 215 | } catch (e) {} 216 | } 217 | 218 | function checkItems() { 219 | var s = activeDocument.selection, i = s.length; 220 | if (i > 0) while (i--) { 221 | if (s[i].stroked || s[i].strokeWidth) return true; 222 | } 223 | } 224 | 225 | if (checkItems()) { 226 | win.center(); 227 | win.show(); 228 | } else { 229 | alert('Please select items that contain a stroke!'); 230 | } -------------------------------------------------------------------------------- /minusOffset.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Program version: Adobe Illustrator CS5+ 4 | Name: minusOffset.jsx; 5 | 6 | Author: Alexander Ladygin, email: i@ladygin.pro 7 | 8 | Copyright (c) 2018 9 | www.ladyginpro.ru 10 | 11 | */ 12 | app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS; 13 | $.getUnits = function (val, def) {return 'px,pt,mm,cm,in,pc'.indexOf(val.slice(-2)) > -1 ? val.slice(-2) : def;}; 14 | $.convertUnits = function (obj, b) {if (obj === undefined) {return obj;}if (b === undefined) {b = 'px';}if (typeof obj === 'number') {obj = obj + 'px';}if (typeof obj === 'string') {var unit = $.getUnits(obj),val = parseFloat(obj);if (unit && !isNaN(val)) {obj = val;}else if (!isNaN(val)) {obj = val; unit = 'px';}}if (((unit === 'px') || (unit === 'pt')) && (b === 'mm')) {obj = parseFloat(obj) / 2.83464566929134;}else if (((unit === 'px') || (unit === 'pt')) && (b === 'cm')) {obj = parseFloat(obj) / (2.83464566929134 * 10);}else if (((unit === 'px') || (unit === 'pt')) && (b === 'in')) {obj = parseFloat(obj) / 72;}else if ((unit === 'mm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134;}else if ((unit === 'mm') && (b === 'cm')) {obj = parseFloat(obj) * 10;}else if ((unit === 'mm') && (b === 'in')) {obj = parseFloat(obj) / 25.4;}else if ((unit === 'cm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134 * 10;}else if ((unit === 'cm') && (b === 'mm')) {obj = parseFloat(obj) / 10;}else if ((unit === 'cm') && (b === 'in')) {obj = parseFloat(obj) * 2.54;}else if ((unit === 'in') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 72;}else if ((unit === 'in') && (b === 'mm')) {obj = parseFloat(obj) * 25.4;}else if ((unit === 'in') && (b === 'cm')) {obj = parseFloat(obj) * 25.4;}return parseFloat(obj);}; 15 | 16 | var scriptName = 'minusOffset', 17 | copyright = ' \u00A9 www.ladyginpro.ru', 18 | settingFile = { 19 | name: scriptName + '__setting.json', 20 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 21 | }, 22 | firstItemName = '__' + scriptName + '__firstName', 23 | $nesting = 1000; 24 | 25 | function getLiveOffsetProps() { 26 | return ''; 31 | } 32 | 33 | function liveOffset (item) { 34 | item.applyEffect(getLiveOffsetProps()); 35 | app.executeMenuCommand('expandStyle'); 36 | return item; 37 | } 38 | 39 | function __group (items, placement) { 40 | var i = items.length; 41 | if (i > 0) { 42 | var $group = activeDocument.groupItems.add(); 43 | $group.moveBefore(placement); 44 | while (i--) items[i].moveToBeginning($group); 45 | return $group; 46 | } 47 | } 48 | 49 | function __ungroup ($group) { 50 | var i = $group.pageItems.length; 51 | if (i > 0) while (i--) $group.pageItems[i].moveBefore($group); 52 | $group.remove(); 53 | } 54 | 55 | function minusOffset (topItem, items, nestingLevel) { 56 | var l = items.length, 57 | removeCollection = []; 58 | 59 | if (l > (!nestingLevel ? 1 : 0)) { 60 | selection = null; 61 | if (!nestingLevel) progressBarCounter = progressBar.maxvalue / l; 62 | 63 | for (var i = (!nestingLevel ? 1 : 0); i < l; i++) { 64 | if (__inGroups.value && (nestingLevel < $nesting) && items[i].typename === 'GroupItem') { 65 | if (items[i].pageItems.length) minusOffset(topItem, items[i].pageItems, nestingLevel + 1); 66 | } 67 | else { 68 | var firstItem = liveOffset(topItem.duplicate()); 69 | firstItem.name = firstItemName; 70 | 71 | __group([items[i], firstItem], items[i]).selected = true; 72 | app.executeMenuCommand('Live Pathfinder Minus Back'); 73 | app.executeMenuCommand('expandStyle'); 74 | try { 75 | selection[0].pageItems.getByName(firstItemName).remove(); 76 | removeCollection.push(selection[0]); 77 | } 78 | catch (e) { 79 | if (selection[0] && selection[0].typename === 'GroupItem') __ungroup(selection[0]); 80 | } 81 | selection = null; 82 | } 83 | 84 | if (!nestingLevel) { 85 | progressBar.value += progressBarCounter; 86 | win.update(); 87 | } 88 | } 89 | var j = removeCollection.length; 90 | if (j > 0) while (j--) removeCollection[j].remove(); 91 | } 92 | 93 | return topItem; 94 | } 95 | 96 | function inputNumberEvents (ev, _input, min, max, callback){ 97 | var step, 98 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 99 | _value = parseFloat(_input.text), 100 | units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 101 | 102 | min = (min === undefined ? 0 : min); 103 | max = (max === undefined ? Infinity : max); 104 | step = (ev.shiftKey ? 10 : (ev.ctrlKey ? .1 : 1)); 105 | 106 | if (isNaN(_value)) { 107 | _input.text = min; 108 | } 109 | else { 110 | _value = ( ((_dir === 'u') || (_dir === 'r')) ? _value + step : (((_dir === 'd') || (_dir === 'l')) ? _value - step : false) ); 111 | if (_value !== false) { 112 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 113 | _input.text = _value; 114 | if (callback instanceof Function) callback(_value, _input, min, max, units); 115 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 116 | } 117 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 118 | } 119 | } 120 | 121 | var win = new Window('dialog', scriptName + copyright); 122 | win.orientation = 'column'; 123 | win.alignChildren = 'fill'; 124 | 125 | win.addEventListener('keydown', function (e) { 126 | if (e.keyName.toLowerCase() === 'enter') { 127 | startAction(); 128 | } 129 | }); 130 | 131 | with (globalGroup = win.add('group')) { 132 | orientation = 'column'; 133 | alignChildren = 'fill'; 134 | 135 | with (add('panel')) { 136 | orientation = 'column'; 137 | alignChildren = 'left'; 138 | 139 | with (add('group')) { 140 | add('statictext', undefined, 'Offset:'); 141 | var __offset = add('edittext', [0, 0, 90, 25], '10 px'); 142 | __offset.active = true; 143 | __offset.addEventListener('keydown', function (e) { inputNumberEvents(e, this, -Infinity, Infinity) }); 144 | } 145 | with (add('group')) { 146 | add('statictext', undefined, 'Joins:'); 147 | var __joins = add('dropdownlist', [0, 0, 97, 25], 'Round,Bevel,Miter'.split(',')); 148 | __joins.selection = 2; 149 | } 150 | with (add('group')) { 151 | add('statictext', undefined, 'Miter limit:'); 152 | var __miterlimit = add('edittext', [0, 0, 70, 25], 4); 153 | __miterlimit.addEventListener('keydown', function (e) { inputNumberEvents(e, this, -Infinity, Infinity) }); 154 | } 155 | var __inGroups = add('checkbox', undefined, 'Each in the group'); 156 | __inGroups.onClick = function() { nestingUIGroup.enabled = this.value; } 157 | __inGroups.value = false; 158 | with (nestingUIGroup = add('group')) { 159 | enabled = false; 160 | add('statictext', undefined, 'Group nesting:'); 161 | var __groupNesting = add('edittext', [0, 0, 45, 25], '1000'); 162 | __groupNesting.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 1, Infinity) }); 163 | } 164 | } 165 | with (add('group')) { 166 | var cancel = add('button', undefined, 'Cancel'); 167 | cancel.helpTip = 'Press Esc to Close'; 168 | cancel.onClick = function () { win.close(); } 169 | 170 | var ok = add('button', undefined, 'Run'); 171 | ok.helpTip = 'Press Enter to Run'; 172 | ok.onClick = startAction; 173 | // ok.active = true; 174 | } 175 | } 176 | var progressBar = win.add('progressbar'), 177 | progressBarCounter = 100; 178 | progressBar.value = progressBar.minvalue = 0; 179 | progressBar.maxvalue = progressBarCounter; 180 | progressBar.maximumSize = [1000, 5]; 181 | 182 | function startAction() { 183 | $nesting = parseInt(__groupNesting.text) || 1000; 184 | globalGroup.enabled = false; 185 | try{ 186 | minusOffset(selection[0], selection, 0); 187 | }catch(err){alert(err + '\n' + err.line);} 188 | win.close(); 189 | } 190 | 191 | function saveSettings() { 192 | var $file = new File(settingFile.folder + settingFile.name), 193 | data = [ 194 | __offset.text, 195 | __miterlimit.text, 196 | __joins.selection.index, 197 | __inGroups.value, 198 | __groupNesting.text 199 | ].toString(); 200 | 201 | $file.open('w'); 202 | $file.write(data); 203 | $file.close(); 204 | } 205 | 206 | function loadSettings() { 207 | var $file = File(settingFile.folder + settingFile.name); 208 | if ($file.exists) { 209 | try { 210 | $file.open('r'); 211 | var data = $file.read().split('\n'), 212 | $main = data[0].split(','); 213 | __offset.text = $main[0]; 214 | __miterlimit.text = $main[1]; 215 | __joins.selection.index = parseInt($main[2]); 216 | __inGroups.value = ($main[3] === 'true'); 217 | __groupNesting.text = $main[4]; 218 | 219 | nestingUIGroup.enabled = __inGroups.value; 220 | } catch (e) {} 221 | $file.close(); 222 | } 223 | } 224 | 225 | win.onClose = function(){ 226 | saveSettings(); 227 | } 228 | 229 | function checkSettingFolder() { 230 | var $folder = new Folder(settingFile.folder); 231 | if (!$folder.exists) $folder.create(); 232 | } 233 | 234 | checkSettingFolder(); 235 | loadSettings(); 236 | win.center(); 237 | win.show(); -------------------------------------------------------------------------------- /createArtboardsFromTheSelection.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ 5 | Name: createArtboardsFromTheSelection.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | 12 | $.errorMessage = function (err) {alert(err + '\n' + err.line);}; 13 | $.getUnits = function (val, def) {return 'px,pt,mm,cm,in,pc'.indexOf(val.slice(-2)) > -1 ? val.slice(-2) : def;}; 14 | $.convertUnits = function (obj, b) {if (obj === undefined) {return obj;}if (b === undefined) {b = 'px';}if (typeof obj === 'number') {obj = obj + 'px';}if (typeof obj === 'string') {var unit = $.getUnits(obj),val = parseFloat(obj);if (unit && !isNaN(val)) {obj = val;}else if (!isNaN(val)) {obj = val; unit = 'px';}}if (((unit === 'px') || (unit === 'pt')) && (b === 'mm')) {obj = parseFloat(obj) / 2.83464566929134;}else if (((unit === 'px') || (unit === 'pt')) && (b === 'cm')) {obj = parseFloat(obj) / (2.83464566929134 * 10);}else if (((unit === 'px') || (unit === 'pt')) && (b === 'in')) {obj = parseFloat(obj) / 72;}else if ((unit === 'mm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134;}else if ((unit === 'mm') && (b === 'cm')) {obj = parseFloat(obj) * 10;}else if ((unit === 'mm') && (b === 'in')) {obj = parseFloat(obj) / 25.4;}else if ((unit === 'cm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134 * 10;}else if ((unit === 'cm') && (b === 'mm')) {obj = parseFloat(obj) / 10;}else if ((unit === 'cm') && (b === 'in')) {obj = parseFloat(obj) * 2.54;}else if ((unit === 'in') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 72;}else if ((unit === 'in') && (b === 'mm')) {obj = parseFloat(obj) * 25.4;}else if ((unit === 'in') && (b === 'cm')) {obj = parseFloat(obj) * 25.4;}return parseFloat(obj);}; 15 | function inputNumberEvents (ev, _input, min, max, callback){ 16 | var step, 17 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 18 | _value = parseFloat(_input.text), 19 | units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 20 | 21 | min = (min === undefined ? 0 : min); 22 | max = (max === undefined ? Infinity : max); 23 | step = (ev.shiftKey ? 10 : (ev.ctrlKey ? .1 : 1)); 24 | 25 | if (isNaN(_value)) { 26 | _input.text = min; 27 | } 28 | else { 29 | _value = ( ((_dir === 'u')) ? _value + step : (((_dir === 'd')) ? _value - step : false) ); 30 | if (_value !== false) { 31 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 32 | _input.text = _value; 33 | if (callback instanceof Function) callback(ev, _value, _input, min, max, units); 34 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 35 | } 36 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 37 | } 38 | } 39 | function doubleValues (ev, __value, items) { 40 | if (ev.altKey && ((ev.keyName === 'Left') || (ev.keyName === 'Right'))) { 41 | var i = items.length; 42 | if (i > 0) while (i--) items[i].text = __value; 43 | } 44 | } 45 | 46 | 47 | var scriptName = 'CAFTS', 48 | copyright = ' \u00A9 www.ladyginpro.ru', 49 | settingFile = { 50 | name: scriptName + '__setting.json', 51 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 52 | }; 53 | 54 | var win = new Window('dialog', 'Create artboard from the selection \u00A9 www.ladyginpro.ru'); 55 | win.orientation = 'column'; 56 | win.alignChildren = ['fill', 'fill']; 57 | 58 | var panel = win.add('panel', undefined, 'Selection bounds:'); 59 | panel.orientation = 'column'; 60 | panel.alignChildren = ['fill', 'fill']; 61 | panel.margins = 20; 62 | 63 | var eachSel = panel.add('radiobutton', undefined, 'Each in the selection'), 64 | selBnds = panel.add('radiobutton', undefined, 'Only selection bounds'), 65 | __itemName = panel.add('checkbox', undefined, 'Set name from element'); 66 | __itemName.value = true; 67 | eachSel.value = true; 68 | eachSel.onClick = function() { __itemName.enabled = true; } 69 | selBnds.onClick = function() { __itemName.value = __itemName.enabled = false; } 70 | 71 | with (panel.add('group')) { 72 | orientation = 'column'; 73 | alignChildren = 'fill'; 74 | 75 | with (add('group')) { 76 | orientation = 'row'; 77 | 78 | with (add('group')) { 79 | orientation = 'column'; 80 | alignChildren = 'left'; 81 | add('statictext', undefined, 'Bleed Top:'); 82 | var bleedTop = add('edittext', [0, 0, 80, 25], '0 px'); 83 | bleedTop.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 0, Infinity); doubleValues(e, this.text, (e.shiftKey ? [bleedTop, bleedRight, bleedBottom, bleedLeft] : [bleedTop, bleedBottom])); }); 84 | } 85 | with (add('group')) { 86 | orientation = 'column'; 87 | alignChildren = 'left'; 88 | add('statictext', undefined, 'Bleed Right:'); 89 | var bleedRight = add('edittext', [0, 0, 80, 25], '0 px'); 90 | bleedRight.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 0, Infinity); doubleValues(e, this.text, (e.shiftKey ? [bleedTop, bleedRight, bleedBottom, bleedLeft] : [bleedRight, bleedLeft])); }); 91 | } 92 | } 93 | with (add('group')) { 94 | orientation = 'row'; 95 | 96 | with (add('group')) { 97 | orientation = 'column'; 98 | alignChildren = 'left'; 99 | add('statictext', undefined, 'Bleed Bottom:'); 100 | var bleedBottom = add('edittext', [0, 0, 80, 25], '0 px'); 101 | bleedBottom.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 0, Infinity); doubleValues(e, this.text, (e.shiftKey ? [bleedTop, bleedRight, bleedBottom, bleedLeft] : [bleedTop, bleedBottom])); }); 102 | } 103 | with (add('group')) { 104 | orientation = 'column'; 105 | alignChildren = 'left'; 106 | add('statictext', undefined, 'Bleed Left:'); 107 | var bleedLeft = add('edittext', [0, 0, 80, 25], '0 px'); 108 | bleedLeft.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 0, Infinity); doubleValues(e, this.text, (e.shiftKey ? [bleedTop, bleedRight, bleedBottom, bleedLeft] : [bleedRight, bleedLeft])); }); 109 | } 110 | } 111 | } 112 | 113 | var panel = win.add('panel', undefined, 'Item bounds:'); 114 | panel.orientation = 'row'; 115 | panel.alignChildren = ['fill', 'fill']; 116 | panel.margins = 20; 117 | 118 | var bndsVis = panel.add('radiobutton', undefined, 'Vsiible'), 119 | bndsGeo = panel.add('radiobutton', undefined, 'Geometric'); 120 | bndsVis.value = true; 121 | 122 | var winButtons = win.add('group'); 123 | winButtons.alignChildren = ['fill', 'fill']; 124 | winButtons.margins = [0, 0, 0, 0]; 125 | 126 | var cancel = winButtons.add('button', undefined, 'Cancel'); 127 | cancel.helpTip = 'Press Esc to Close'; 128 | cancel.onClick = function () { win.close(); } 129 | 130 | var ok = winButtons.add('button', [0, 0, 100, 30], 'OK'); 131 | ok.helpTip = 'Press Enter to Run'; 132 | ok.onClick = startAction; 133 | ok.active = true; 134 | 135 | function startAction() { 136 | var items = selection, 137 | i = items.length, 138 | $bounds = [], 139 | bleed = [ 140 | $.convertUnits(bleedLeft.text, 'px'), 141 | $.convertUnits(bleedTop.text, 'px'), 142 | $.convertUnits(bleedRight.text, 'px'), 143 | $.convertUnits(bleedBottom.text, 'px') 144 | ], 145 | bounds = (bndsVis.value ? 'visible' : 'geometric') + 'Bounds'; 146 | 147 | if (eachSel.value) { 148 | while (i--) { 149 | $bounds = [ 150 | items[i][bounds][0] - bleed[0], 151 | items[i][bounds][1] + bleed[1], 152 | items[i][bounds][2] + bleed[2], 153 | items[i][bounds][3] - bleed[3] 154 | ]; 155 | if (__itemName.value && items[i].name) activeDocument.artboards.add($bounds).name = items[i].name; 156 | else activeDocument.artboards.add($bounds); 157 | } 158 | } 159 | else { 160 | var x = [], y = [], 161 | w = [], h = []; 162 | while (i--) { 163 | x.push(items[i][bounds][0]); 164 | y.push(items[i][bounds][1]); 165 | w.push(items[i][bounds][2]); 166 | h.push(items[i][bounds][3]); 167 | }; 168 | activeDocument.artboards.add([ 169 | Math.min.apply(null, x) - bleed[0], 170 | Math.max.apply(null, y) + bleed[1], 171 | Math.max.apply(null, w) + bleed[2], 172 | Math.min.apply(null, h) - bleed[3] 173 | ]); 174 | } 175 | 176 | win.close(); 177 | } 178 | 179 | 180 | function saveSettings() { 181 | var $file = new File(settingFile.folder + settingFile.name), 182 | data = [ 183 | eachSel.value, 184 | selBnds.value, 185 | __itemName.value, 186 | bndsVis.value, 187 | bndsGeo.value, 188 | bleedTop.text, 189 | bleedRight.text, 190 | bleedBottom.text, 191 | bleedLeft.text 192 | ].toString(); 193 | 194 | $file.open('w'); 195 | $file.write(data); 196 | $file.close(); 197 | } 198 | 199 | function loadSettings() { 200 | var $file = File(settingFile.folder + settingFile.name); 201 | if ($file.exists) { 202 | try { 203 | $file.open('r'); 204 | var data = $file.read().split('\n'), 205 | $main = data[0].split(','); 206 | eachSel.value = ($main[0] === 'true'); 207 | selBnds.value = ($main[1] === 'true'); 208 | __itemName.value = ($main[2] === 'true'); 209 | bndsVis.value = ($main[3] === 'true'); 210 | bndsGeo.value = ($main[4] === 'true'); 211 | bleedTop.text = $main[5]; 212 | bleedRight.text = $main[6]; 213 | bleedBottom.text = $main[7]; 214 | bleedLeft.text = $main[8]; 215 | 216 | __itemName.enabled = selBnds.value; 217 | __itemName.value = __itemName.enabled = !selBnds.value; 218 | } catch (e) {} 219 | $file.close(); 220 | } 221 | } 222 | 223 | win.onClose = function () { 224 | saveSettings(); 225 | return true; 226 | } 227 | 228 | function checkSettingFolder() { 229 | var $folder = new Folder(settingFile.folder); 230 | if (!$folder.exists) $folder.create(); 231 | } 232 | 233 | checkSettingFolder(); 234 | loadSettings(); 235 | win.center(); 236 | win.show(); -------------------------------------------------------------------------------- /replaceItems.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ 5 | Name: replaceItems.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | 12 | var scriptName = 'ReplaceItems', 13 | settingFile = { 14 | name: scriptName + '__setting.json', 15 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 16 | }; 17 | 18 | var win = new Window('dialog', scriptName + ' \u00A9 www.ladyginpro.ru'); 19 | win.orientation = 'column'; 20 | win.alignChildren = ['fill', 'fill']; 21 | 22 | with (win.add('group')) { 23 | orientation = 'row'; 24 | 25 | var panel = add('panel', undefined, 'What to replace?'); 26 | panel.orientation = 'column'; 27 | panel.alignChildren = ['fill', 'fill']; 28 | panel.margins = [20, 30, 20, 20]; 29 | 30 | var bufferRadio = panel.add('radiobutton', undefined, 'Object in buffer'), 31 | currentRadio = panel.add('radiobutton', undefined, 'Top object'), 32 | groupSuccessively = panel.add('radiobutton', undefined, 'All in group (successively)'), 33 | randomRadio = panel.add('radiobutton', undefined, 'All in group (random)'), 34 | groupValue = panel.add('group'), 35 | randomValue = groupValue.add('edittext', undefined, '100'), 36 | randomValueUnit = groupValue.add('statictext', undefined, '%'), 37 | elementsInGroupCheckbox = panel.add('checkbox', undefined, 'Replace items in a group?'); 38 | 39 | groupValue.orientation = 'row'; 40 | groupValue.margins = 0; 41 | groupValue.alignChildren = ['fill', 'fill']; 42 | randomValue.minimumSize = [140, undefined]; 43 | 44 | var panelCheckboxes = add('panel'); 45 | panelCheckboxes.orientation = 'column'; 46 | panelCheckboxes.alignChildren = ['fill', 'fill']; 47 | panelCheckboxes.margins = 20; 48 | 49 | var fitInSizeCheckbox = panelCheckboxes.add('checkbox', undefined, 'Fit to element size'); 50 | copyWHCheckbox = panelCheckboxes.add('checkbox', undefined, 'Copy Width & Height'); 51 | saveOriginalCheckbox = panelCheckboxes.add('checkbox', undefined, 'Save original element'), 52 | copyColorsCheckbox = panelCheckboxes.add('checkbox', undefined, 'Copy colors from element'), 53 | randomRotateCheckbox = panelCheckboxes.add('checkbox', undefined, 'Random element rotation'), 54 | symbolByRPCheckbox = panelCheckboxes.add('checkbox', [0, 0, 100, 40], 'Align symbols by\nregistration point'); 55 | 56 | bufferRadio.value = true; 57 | fitInSizeCheckbox.value = false; 58 | copyWHCheckbox.value = false; 59 | saveOriginalCheckbox.value = false; 60 | 61 | } 62 | 63 | var winButtons = win.add('group'); 64 | winButtons.alignChildren = ['fill', 'fill']; 65 | winButtons.margins = [0, 0, 0, 0]; 66 | 67 | var cancel = winButtons.add('button', undefined, 'Cancel'); 68 | cancel.helpTip = 'Press Esc to Close'; 69 | cancel.onClick = function () { win.close(); } 70 | 71 | var ok = winButtons.add('button', [0, 0, 100, 30], 'OK'); 72 | ok.helpTip = 'Press Enter to Run'; 73 | ok.onClick = startAction; 74 | ok.active = true; 75 | 76 | var progressBar = win.add('progressbar', [0, 0, 110, 5]), 77 | progressBarCounter = 100; 78 | progressBar.value = 0; 79 | progressBar.minvalue = 0; 80 | progressBar.maxvalue = progressBarCounter; 81 | 82 | copyWHCheckbox.onClick = function (e) { 83 | groupValue.enabled = !copyWHCheckbox.value; 84 | fitInSizeCheckbox.enabled = !this.value; 85 | } 86 | 87 | fitInSizeCheckbox.onClick = function (e) { 88 | copyWHCheckbox.enabled = !this.value; 89 | } 90 | 91 | function randomRotation (item) { 92 | item.rotate(Math.floor(Math.random() * 360), true, true, true, true, Transformation.CENTER); 93 | } 94 | 95 | function setFillColor (items, color) { 96 | if (color) { 97 | var i = items.length; 98 | if (i) while (i--) { 99 | if (items[i].typename === 'GroupItem') { 100 | setFillColor(items[i].pageItems, color); 101 | } 102 | else if (items[i].typename === 'CompoundPathItem') { 103 | if (items[i].pathItems.length) items[i].pathItems[0].fillColor = color; 104 | } 105 | else if (items[i].typename === 'PathItem') { 106 | items[i].fillColor = color; 107 | } 108 | } 109 | } 110 | } 111 | 112 | function getFillColor (items) { 113 | var i = items.length, gc; 114 | if (i) while (i--) { 115 | if (items[i].typename === 'GroupItem' && (gc = getFillColor(items[i].pageItems))) return gc; 116 | else if (items[i].typename === 'CompoundPathItem' && items[i].pathItems.length) return items[i].pathItems[0].fillColor; 117 | else if (items[i].typename === 'PathItem') return items[i].fillColor; 118 | } 119 | } 120 | 121 | function getSymbolPositionByRegistrationPoint (item) { 122 | var bakupSymbol = item.symbol, 123 | newSymbol = activeDocument.symbols.add(item, SymbolRegistrationPoint.SYMBOLTOPLEFTPOINT); 124 | 125 | // replace symbol 126 | item.symbol = newSymbol; 127 | 128 | // set position 129 | var position = [ 130 | item.left, 131 | item.top 132 | ]; 133 | 134 | // restore symbol 135 | item.symbol = bakupSymbol; 136 | newSymbol.remove(); 137 | 138 | return position; 139 | } 140 | 141 | function startAction() { 142 | if (selection.length) { 143 | panel.enabled = groupValue.enabled = panelCheckboxes.enabled = ok.enabled = cancel.enabled = false; 144 | 145 | var __ratio = !isNaN(parseFloat(randomValue.text)) ? parseFloat(randomValue.text) / 100 : 1, 146 | items = (!elementsInGroupCheckbox.value ? selection : selection[selection.length - 1].pageItems), 147 | nodes = (currentRadio.value ? selection[0] : (bufferRadio.value ? [] : selection[0].pageItems)), 148 | length = nodes.length, 149 | i = items.length, 150 | j = 0; 151 | 152 | progressBarCounter = progressBar.maxvalue / i; 153 | 154 | if (bufferRadio.value) { 155 | selection = null; 156 | app.paste(); 157 | nodes = selection[0]; 158 | selection = null; 159 | } 160 | 161 | function getNode (__index) { 162 | return ((currentRadio.value || bufferRadio.value) ? nodes : nodes[ typeof __index === 'number' ? __index : Math.floor(Math.random() * length) ]); 163 | } 164 | 165 | while (i--) { 166 | if (!bufferRadio.value && !i) break; 167 | if (j >= nodes.length) j = 0; 168 | var item = items[i], 169 | node = getNode(groupSuccessively.value ? j : undefined).duplicate(item, ElementPlacement.PLACEBEFORE), 170 | __fn = 'height', 171 | __fnReverse = 'width'; 172 | 173 | j++; 174 | 175 | if (node.height <= node.width) { 176 | __fn = 'width'; 177 | __fnReverse = 'height'; 178 | } 179 | 180 | if (randomRotateCheckbox.value) randomRotation(node); 181 | 182 | if (!copyWHCheckbox.value) { 183 | var __size = (item.height >= item.width ? item.width : item.height) * __ratio, 184 | precent = __size * 100 / node[__fn] / 100; 185 | 186 | if (fitInSizeCheckbox.value) { 187 | node[__fn] = __size; 188 | node[__fnReverse] *= precent; 189 | } 190 | } 191 | else { 192 | node.width = item.width; 193 | node.height = item.height; 194 | } 195 | 196 | node.left = item.left - (node.width - item.width) / 2; 197 | node.top = item.top + (node.height - item.height) / 2; 198 | 199 | if (symbolByRPCheckbox.value && node.typename === 'SymbolItem') { 200 | var __pos = getSymbolPositionByRegistrationPoint(node); 201 | node.left += (item.left + item.width / 2) - __pos[0]; 202 | node.top += (item.top - item.height / 2) - __pos[1]; 203 | } 204 | 205 | if (copyColorsCheckbox.value) { 206 | setFillColor([node], getFillColor([item])); 207 | } 208 | if (!saveOriginalCheckbox.value) item.remove(); 209 | 210 | progressBar.value += progressBarCounter; 211 | win.update(); 212 | } 213 | 214 | if (bufferRadio.value) nodes.remove(); 215 | 216 | } 217 | 218 | win.close(); 219 | } 220 | 221 | function saveSettings() { 222 | var $file = new File(settingFile.folder + settingFile.name), 223 | data = [ 224 | bufferRadio.value, 225 | currentRadio.value, 226 | randomRadio.value, 227 | elementsInGroupCheckbox.value, 228 | copyWHCheckbox.value, 229 | saveOriginalCheckbox.value, 230 | copyColorsCheckbox.value, 231 | randomRotateCheckbox.value, 232 | symbolByRPCheckbox.value, 233 | randomValue.text, 234 | groupSuccessively.value, 235 | fitInSizeCheckbox.value 236 | ].toString(); 237 | 238 | $file.open('w'); 239 | $file.write(data); 240 | $file.close(); 241 | } 242 | 243 | function loadSettings() { 244 | var $file = File(settingFile.folder + settingFile.name); 245 | if ($file.exists) { 246 | try { 247 | $file.open('r'); 248 | var data = $file.read().split('\n'), 249 | $main = data[0].split(','); 250 | bufferRadio.value = ($main[0] === 'true'); 251 | currentRadio.value = ($main[1] === 'true'); 252 | randomRadio.value = ($main[2] === 'true'); 253 | elementsInGroupCheckbox.value = ($main[3] === 'true'); 254 | copyWHCheckbox.value = ($main[4] === 'true'); 255 | saveOriginalCheckbox.value = ($main[5] === 'true'); 256 | copyColorsCheckbox.value = ($main[6] === 'true'); 257 | randomRotateCheckbox.value = ($main[7] === 'true'); 258 | symbolByRPCheckbox.value = ($main[8] === 'true'); 259 | randomValue.text = $main[9]; 260 | groupSuccessively.value = ($main[10] === 'true'); 261 | fitInSizeCheckbox.value = ($main[11] === 'true'); 262 | 263 | groupValue.enabled = !copyWHCheckbox.value; 264 | fitInSizeCheckbox.enabled = !copyWHCheckbox.value; 265 | copyWHCheckbox.enabled = !fitInSizeCheckbox.value; 266 | } catch (e) {} 267 | $file.close(); 268 | } 269 | } 270 | 271 | win.onClose = function() { 272 | saveSettings(); 273 | return true; 274 | } 275 | 276 | function checkSettingFolder() { 277 | var $folder = new Folder(settingFile.folder); 278 | if (!$folder.exists) $folder.create(); 279 | } 280 | 281 | checkSettingFolder(); 282 | loadSettings(); 283 | win.center(); 284 | win.show(); -------------------------------------------------------------------------------- /artboardsResizeWithObjects.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Program version: Adobe Illustrator CS5+ 4 | Name: artboardResizeWithObjects.jsx; 5 | 6 | Author: Alexander Ladygin, email: i@ladygin.pro 7 | Thanks for refactoring and testing - Sergey Osokin, email: hi@sergosokin.ru 8 | 9 | Copyright (c) 2018 10 | www.ladyginpro.ru 11 | 12 | */ 13 | 14 | #target illustrator; 15 | 16 | var lockedItems = [], 17 | hiddenItems = []; 18 | 19 | function getDocUnit() { 20 | var unit = activeDocument.rulerUnits.toString().replace('RulerUnits.', ''); 21 | switch (unit) { 22 | case 'Points' : ; 23 | case 'Pixels' : unit = 'px'; break; 24 | case 'Millimeters' : unit = 'mm'; break; 25 | case 'Centimeters' : unit = 'cm'; break; 26 | case 'Inches' : unit = 'in'; break; 27 | } 28 | 29 | return unit; 30 | } 31 | 32 | function convertUnits (value, newUnit) { 33 | var unit = ((typeof value === 'string' && 'pt,px,mm,cm,in'.indexOf(value.slice(-2)) > -1) ? value.slice(-2) : getDocUnit()); 34 | 35 | if (((unit === 'px') || (unit === 'pt')) && (newUnit === 'mm')) { 36 | value = parseFloat(value) / 2.83464566929134; 37 | } 38 | else if (((unit === 'px') || (unit === 'pt')) && (newUnit === 'cm')) { 39 | value = parseFloat(value) / (2.83464566929134 * 10); 40 | } 41 | else if (((unit === 'px') || (unit === 'pt')) && (newUnit === 'in')) { 42 | value = parseFloat(value) / 72; 43 | } 44 | else if ((unit === 'mm') && ((newUnit === 'px') || (newUnit === 'pt'))) { 45 | value = parseFloat(value) * 2.83464566929134; 46 | } 47 | else if ((unit === 'mm') && (newUnit === 'cm')) { 48 | value = parseFloat(value) * 10; 49 | } 50 | else if ((unit === 'mm') && (newUnit === 'in')) { 51 | value = parseFloat(value) / 25.4; 52 | } 53 | else if ((unit === 'cm') && ((newUnit === 'px') || (newUnit === 'pt'))) { 54 | value = parseFloat(value) * 2.83464566929134 * 10; 55 | } 56 | else if ((unit === 'cm') && (newUnit === 'mm')) { 57 | value = parseFloat(value) / 10; 58 | } 59 | else if ((unit === 'cm') && (newUnit === 'in')) { 60 | value = parseFloat(value) * 2.54; 61 | } 62 | else if ((unit === 'in') && ((newUnit === 'px') || (newUnit === 'pt'))) { 63 | value = parseFloat(value) * 72; 64 | } 65 | else if ((unit === 'in') && (newUnit === 'mm')) { 66 | value = parseFloat(value) * 25.4; 67 | } 68 | else if ((unit === 'in') && (newUnit === 'cm')) { 69 | value = parseFloat(value) * 25.4; 70 | } 71 | 72 | return parseFloat(value); 73 | } 74 | 75 | function getArtboardValues (__index) { 76 | var art = activeDocument.artboards[((typeof __index === 'number' && __index > -1 && __index < activeDocument.artboards.length) ? __index : activeDocument.artboards.getActiveArtboardIndex())], 77 | rect = art.artboardRect; 78 | return { 79 | art: art, 80 | width: rect[2] - rect[0], 81 | height: -(rect[3] - rect[1]) 82 | }; 83 | } 84 | 85 | function saveItemsState() { 86 | for (var i = 0; i < activeDocument.pageItems.length; i++) { 87 | var currItem = activeDocument.pageItems[i]; 88 | if (currItem.locked == true) { 89 | lockedItems.push(i); 90 | currItem.locked = false; 91 | } 92 | if (currItem.hidden == true) { 93 | hiddenItems.push(i); 94 | currItem.hidden = false; 95 | } 96 | } 97 | } 98 | 99 | function restoreItemsState() { 100 | for (var i = 0; i < lockedItems.length; i++) { 101 | var index = lockedItems[i]; 102 | activeDocument.pageItems[index].locked = true; 103 | } 104 | for (var j = 0; j < hiddenItems.length; j++) { 105 | var index = hiddenItems[j]; 106 | activeDocument.pageItems[index].hidden = true; 107 | } 108 | } 109 | 110 | function resizeArtboardWithObjects (__size, __mode, __artNum) { 111 | if (__size !== 0) { 112 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM; 113 | 114 | var selectionBak = selection, 115 | __art = getArtboardValues(__artNum), 116 | art = getArtboardValues(__artNum).art, 117 | rect = art.artboardRect, 118 | artSize = { 119 | width: __art.width, 120 | height: __art.height, 121 | }; 122 | 123 | selection = null; 124 | 125 | function getResizeValue (value) { 126 | var result = value; 127 | 128 | if (typeof value === 'number') { 129 | result = (convertUnits(value + getDocUnit(), 'px') / artSize[__mode]); 130 | } 131 | else if (typeof value === 'string' && value.length) { 132 | if (value[value.length-1] === '%') { 133 | result = parseFloat(value) / 100; 134 | } 135 | } 136 | else { 137 | result = null; 138 | } 139 | 140 | return result; 141 | } 142 | 143 | var resizeValue = getResizeValue(__size); 144 | 145 | if (resizeValue !== null) { 146 | activeDocument.selectObjectsOnActiveArtboard(); 147 | 148 | var items = selection, 149 | i = j = selection.length; 150 | 151 | art.artboardRect = [ 152 | rect[0], rect[1], 153 | rect[0] + artSize.width * resizeValue, 154 | rect[1] - artSize.height * resizeValue 155 | ]; 156 | 157 | while (i--) { 158 | items[i].resize(resizeValue * 100, resizeValue * 100, true, true, true, true, resizeValue * 100, Transformation.TOPLEFT); 159 | items[i].position = [items[i].position[0] * resizeValue, items[i].position[1] * resizeValue]; 160 | } 161 | } 162 | 163 | selection = selectionBak; 164 | } 165 | } 166 | 167 | var win = new Window('dialog', 'Resize artboard with objects \u00A9 www.ladyginpro.ru', undefined); 168 | win.orientation = 'column'; 169 | win.alignChildren = ['fill', 'fill']; 170 | 171 | panel = win.add('panel', undefined, 'Resize artboard:'); 172 | panel.orientation = 'column'; 173 | panel.alignChildren = ['fill', 'fill']; 174 | 175 | var winScale = panel.add('radiobutton', undefined, 'New scale factor'), 176 | winWidth = panel.add('radiobutton', undefined, 'New artboard width'), 177 | winHeight = panel.add('radiobutton', undefined, 'New artboard height'); 178 | winWidth.value = true; 179 | 180 | var artGroup = win.add('panel'); 181 | artGroup.orientation = 'column'; 182 | artGroup.alignChildren = ['fill', 'fill']; 183 | 184 | var winArtActive = artGroup.add('radiobutton', undefined, 'Only active artboard'), 185 | winArtAll = artGroup.add('radiobutton', undefined, 'All artboards'), 186 | winArtCustom = artGroup.add('radiobutton', undefined, 'Custom artboards'), 187 | winArtNum = artGroup.add('edittext', undefined, activeDocument.artboards.getActiveArtboardIndex() + 1); 188 | winArtActive.value = true; 189 | winArtNum.enabled = false; 190 | 191 | var optGroup = win.add('panel'); 192 | optGroup.orientation = 'column'; 193 | optGroup.alignChildren = ['fill', 'fill']; 194 | 195 | var winAllItems = optGroup.add('checkbox', undefined, 'Include hidden & locked items'); 196 | winAllItems.value = false; 197 | 198 | var editGroup = win.add('panel'); 199 | editGroup.orientation = 'row'; 200 | editGroup.alignChildren = ['fill', 'fill']; 201 | 202 | var winValue = editGroup.add('edittext', undefined, Math.round(convertUnits(getArtboardValues().width + 'px', getDocUnit()))), 203 | winUnit = editGroup.add('statictext', undefined, getDocUnit()); 204 | winValue.minimumSize = [120, undefined]; 205 | winValue.active = true; 206 | 207 | var winButtons = win.add('group'); 208 | winButtons.alignChildren = ['fill', 'fill']; 209 | winButtons.margins = [0, 0, 0, 0]; 210 | 211 | var cancel = winButtons.add('button', undefined, 'Cancel'); 212 | cancel.helpTip = 'Press Esc to Close'; 213 | cancel.onClick = function () { win.close(); } 214 | 215 | var ok = winButtons.add('button', [0, 0, 100, 30], 'OK'); 216 | ok.helpTip = 'Press Enter to Run'; 217 | ok.onClick = startAction; 218 | ok.active = true; 219 | 220 | 221 | // events 222 | winScale.onClick = function (e) { winUnit.text = '%'; }; 223 | winWidth.onClick = winHeight.onClick = function (e) { winUnit.text = getDocUnit(); }; 224 | 225 | winArtCustom.onClick = function (e) { winArtNum.enabled = true; }; 226 | winArtActive.onClick = winArtAll.onClick = function (e) { winArtNum.enabled = false; }; 227 | 228 | 229 | function getCustomNumbers ($str, items, returnItems) { 230 | var __num = $str.replace(/ /g, '').replace(/[^-0-9^,]/gim,'').split(','), 231 | $maxItems = items.length, 232 | j = __num.length, 233 | arr = []; 234 | 235 | function getNumbersBetweenMinMax (min, max) { 236 | var numbers = []; 237 | for (var n = min; n <= max; n++) { 238 | if (n < $maxItems) { 239 | numbers.push(returnItems ? items[n] : n); 240 | } 241 | } 242 | return numbers; 243 | } 244 | 245 | while (j--) { 246 | if (__num[j].indexOf('-') > -1) { 247 | var values = __num[j].split('-'), 248 | min = parseInt(values[0]), 249 | max = parseInt(values[1]); 250 | 251 | if (!isNaN(min) && !isNaN(max)) arr = arr.concat(getNumbersBetweenMinMax(min - 1, max - 1)); 252 | } 253 | else { 254 | var __val = parseInt(__num[j]); 255 | if (!isNaN(__val) && __val <= $maxItems) { 256 | arr.push(returnItems ? items[__val - 1] : __val - 1); 257 | } 258 | } 259 | } 260 | 261 | return arr; 262 | } 263 | 264 | 265 | function startAction() { 266 | var $size = (winScale.value ? parseInt(winValue.text) + '%' : parseInt(winValue.text)) || 0, 267 | $mode = (winHeight.value ? 'height' : 'width'); 268 | 269 | if (winAllItems.value) { 270 | saveItemsState(); 271 | } 272 | if (winArtActive.value) { 273 | resizeArtboardWithObjects($size, $mode); 274 | } 275 | else if (winArtAll.value) { 276 | var i = activeDocument.artboards.length; 277 | while (i--) { 278 | activeDocument.artboards.setActiveArtboardIndex(i); 279 | resizeArtboardWithObjects($size, $mode, i); 280 | } 281 | } 282 | else { 283 | var arr = getCustomNumbers(winArtNum.text, activeDocument.artboards), 284 | i = arr.length; 285 | while (i--) { 286 | activeDocument.artboards.setActiveArtboardIndex(arr[i]); 287 | resizeArtboardWithObjects($size, $mode, arr[i]); 288 | } 289 | } 290 | if (winAllItems.value) { 291 | restoreItemsState(); 292 | } 293 | 294 | win.close(); 295 | } 296 | 297 | // open window 298 | win.center(); 299 | win.show(); -------------------------------------------------------------------------------- /bigBang.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ (presumably in Adobe Illustrator CS6 - did not test) 5 | Name: bigBang.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | 12 | $.errorMessage = function (err) {alert(err + '\n' + err.line);}; 13 | Object.prototype.extend = function (userObject, deep) {try {for (var key in userObject) {if (this.hasOwnProperty(key)) {if (deep&& this[key] instanceof Object&& !(this[key] instanceof Array)&& userObject[key] instanceof Object&& !(userObject[key] instanceof Array)) {this[key].extend(userObject[key], deep);}else this[key] = userObject[key];}}return this;}catch (e) {$.errorMessage('$.objectParser() - error: ' + e);}}; 14 | $.getBounds = function (arr, bounds) {bounds = bounds || 'geometricBounds';bounds = (bounds && bounds.toLowerCase().indexOf('bounds') === -1) ? bounds += 'Bounds' : bounds;var x = [], y = [], w = [], h = [];for (var i = 0; i < arr.length; i++) {x.push(arr[i][bounds][0]);y.push(arr[i][bounds][1]);w.push(arr[i][bounds][2]);h.push(arr[i][bounds][3]);};return [Math.min.apply(null, x), Math.max.apply(null, y), Math.max.apply(null, w), Math.min.apply(null, h)];}; 15 | $.getUnits = function (val, def) {return 'px,pt,mm,cm,in,pc'.indexOf(val.slice(-2)) > -1 ? val.slice(-2) : def;}; 16 | $.convertUnits = function (obj, b) {if (obj === undefined) {return obj;}if (b === undefined) {b = 'px';}if (typeof obj === 'number') {obj = obj + 'px';}if (typeof obj === 'string') {var unit = $.getUnits(obj),val = parseFloat(obj);if (unit && !isNaN(val)) {obj = val;}else if (!isNaN(val)) {obj = val; unit = 'px';}}if (((unit === 'px') || (unit === 'pt')) && (b === 'mm')) {obj = parseFloat(obj) / 2.83464566929134;}else if (((unit === 'px') || (unit === 'pt')) && (b === 'cm')) {obj = parseFloat(obj) / (2.83464566929134 * 10);}else if (((unit === 'px') || (unit === 'pt')) && (b === 'in')) {obj = parseFloat(obj) / 72;}else if ((unit === 'mm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134;}else if ((unit === 'mm') && (b === 'cm')) {obj = parseFloat(obj) * 10;}else if ((unit === 'mm') && (b === 'in')) {obj = parseFloat(obj) / 25.4;}else if ((unit === 'cm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134 * 10;}else if ((unit === 'cm') && (b === 'mm')) {obj = parseFloat(obj) / 10;}else if ((unit === 'cm') && (b === 'in')) {obj = parseFloat(obj) * 2.54;}else if ((unit === 'in') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 72;}else if ((unit === 'in') && (b === 'mm')) {obj = parseFloat(obj) * 25.4;}else if ((unit === 'in') && (b === 'cm')) {obj = parseFloat(obj) * 25.4;}return parseFloat(obj);}; 17 | 18 | 19 | var scriptName = 'bigBang', 20 | copyright = ' \u00A9 www.ladyginpro.ru', 21 | settingFile = { 22 | name: scriptName + '__setting.json', 23 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 24 | }, 25 | isUndo = false, 26 | $count = selection.length; 27 | 28 | function getRandomArbitrary(min, max) { 29 | return Math.random() * (max - min) + min; 30 | } 31 | 32 | function bigBang (items, userOptions) { 33 | try { 34 | var options = { 35 | offset: 100, 36 | delta: 100, 37 | keyObject: 0, 38 | isKeyObject: false, 39 | }.extend(userOptions || {}); 40 | 41 | options.offset = $.convertUnits(options.offset, 'px'); 42 | 43 | var delta = (options.delta > 0 ? 1 : 0) + options.delta / 100, 44 | BNDS = 'geometricBounds', 45 | gbnds = (options.isKeyObject ? selection[options.keyObject][BNDS] : $.getBounds(selection, BNDS)), 46 | x1 = gbnds[0] + (gbnds[2] - gbnds[0]) / 2, 47 | y1 = gbnds[1] - (gbnds[1] - gbnds[3]) / 2; 48 | 49 | var normalizePreview = activeDocument.pathItems.add(); 50 | normalizePreview.remove(); 51 | 52 | function elementShift (item) { 53 | var ibnds = item[BNDS], 54 | $w = (ibnds[2] - ibnds[0]) / 2, 55 | $h = (ibnds[1] - ibnds[3]) / 2, 56 | x2 = ibnds[0] + $w, 57 | y2 = ibnds[1] - $h, 58 | u = Math.atan2(y1 - y2, x1 - x2), 59 | d = (Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2))) + options.offset; 60 | 61 | // if (delta) d *= delta; 62 | // if (delta) d *= Math.sqrt(x1 + y1); 63 | var distSq = (x1 * x2 + y1 * y2); 64 | var f = ((39.5 * 0.08) / (distSq * Math.sqrt(distSq + 0.15)) * delta).toFixed(4); 65 | d += f; 66 | alert(f); 67 | 68 | var cos = Math.cos(u) * d, 69 | sin = Math.sin(u) * d, 70 | x3 = x1 + (cos < 0 ? cos * -1 : cos) * (x2 > x1 ? 1 : -1), 71 | y3 = y1 + (sin > 0 ? sin * -1 : sin) * (y2 > y1 ? -1 : 1); 72 | 73 | item.position = [x3 - $w, y3 + $h]; 74 | } 75 | 76 | var l = items.length; 77 | for (var i = 0; i < l; i++) { 78 | if (options.isKeyObject && i === options.keyObject) continue; 79 | elementShift(items[i]); 80 | } 81 | 82 | return items; 83 | }catch(e) { 84 | alert(e + '\n' + e.line); 85 | } 86 | } 87 | 88 | 89 | function inputNumberEvents (ev, _input, min, max, callback){ 90 | var step, 91 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 92 | _value = parseFloat(_input.text), 93 | units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 94 | 95 | min = (min === undefined ? 0 : min); 96 | max = (max === undefined ? Infinity : max); 97 | step = (ev.shiftKey ? 10 : (ev.ctrlKey ? .1 : 1)); 98 | 99 | if (isNaN(_value)) { 100 | _input.text = min; 101 | } 102 | else { 103 | _value = ( ((_dir === 'u') || (_dir === 'r')) ? _value + step : (((_dir === 'd') || (_dir === 'l')) ? _value - step : false) ); 104 | if (_value !== false) { 105 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 106 | _input.text = _value; 107 | if (callback instanceof Function) callback(_value, _input, min, max, units); 108 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 109 | } 110 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 111 | } 112 | } 113 | 114 | var win = new Window('dialog', scriptName + copyright); 115 | 116 | win.alignChildren = ['fill', 'fill']; 117 | 118 | with (panel = win.add('panel', undefined, 'Offset')) { 119 | alignChildren = ['fill', 'bottom']; 120 | 121 | with (add('group')) { 122 | orientation = 'row'; 123 | 124 | var __offsetSlider = add('slider', [0, 0, 250, 15], 0, -300, 300), 125 | __offset = add('edittext', [0, 0, 50, 25], '0 px'); 126 | __offsetSlider.onChanging = function (e) { 127 | var units = (',px,pt,mm,cm,in,'.indexOf(__offset.text.length > 2 ? (',' + __offset.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? __offset.text.replace(/ /g, '').slice(-2) : '') 128 | __offset.text = Math.round(this.value) + (units ? ' ' + units : ''); 129 | } 130 | __offsetSlider.onChange = function (e) { previewStart(); } 131 | __offset.addEventListener('keydown', function (e) { inputNumberEvents(e, this, -Infinity, Infinity); if (this.text === 'Infinity') { this.text = 0; } }); 132 | __offset.addEventListener('keyup', function (e) { __offsetSlider.value = Math.round(this.text); previewStart(); }); 133 | } 134 | with (add('group')) { 135 | orientation = 'row'; 136 | 137 | var __isKeyObject = add('checkbox', undefined, 'Key object'), 138 | __keyObject = add('slider', [0, 0, 170, 15], 1, 1, $count); 139 | __keyObjectTitle = add('statictext', [0, 0, 40, 25], 1); 140 | __keyObjectTitle.justify = 'center'; 141 | __keyObject.enabled = __keyObjectTitle.enabled = __isKeyObject.value; 142 | __isKeyObject.onClick = function (e) { __keyObject.enabled = __keyObjectTitle.enabled = Math.round(this.value); previewStart(); } 143 | __keyObject.onChanging = function (e) { __keyObjectTitle.text = Math.round(this.value); } 144 | __keyObject.onChange = function (e) { previewStart(); } 145 | } 146 | with (add('group')) { 147 | orientation = 'row'; 148 | 149 | add('statictext', undefined, 'Delta:'); 150 | var __deltaSlider = add('slider', [0, 0, 204, 15], 0, -100, 100), 151 | __delta = add('edittext', [0, 0, 50, 25], 0); 152 | __deltaSlider.onChanging = function (e) { __delta.text = Math.round(this.value) } 153 | __deltaSlider.onChange = function (e) { previewStart(); } 154 | __delta.addEventListener('keydown', function (e) { inputNumberEvents(e, this, -Infinity, Infinity); if (this.text === 'Infinity') this.text = __deltaSlider.text = 0; }); 155 | __delta.addEventListener('keyup', function (e) { __deltaSlider.value = Math.round(this.text); previewStart(); }); 156 | } 157 | } 158 | with (win.add('group')) { 159 | orientation = 'row'; 160 | alignChildren = ['fill', 'fill']; 161 | 162 | var preview = add('checkbox', undefined, 'Preview'), 163 | cancelBtn = add('button', undefined, 'Cancel'), 164 | applyBtn = add('button', undefined, 'OK'); 165 | 166 | preview.onClick = function() { previewStart(); } 167 | cancelBtn.onClick = function() { win.close(); } 168 | applyBtn.onClick = function() { 169 | if (preview.value && isUndo) { 170 | isUndo = false; 171 | win.close(); 172 | } 173 | else { 174 | if (isUndo) app.undo(); 175 | startAction(); 176 | isUndo = false; 177 | win.close(); 178 | } 179 | } 180 | } 181 | 182 | function getData() { 183 | return { 184 | offset: __offset.text, 185 | delta: parseFloat(__delta.text), 186 | isKeyObject: __isKeyObject.value, 187 | keyObject: Math.round(__keyObject.value) - 1, 188 | }; 189 | } 190 | 191 | 192 | function startAction() { 193 | bigBang(selection, getData()); 194 | } 195 | 196 | function previewStart() { 197 | if (preview.value) { 198 | if (isUndo) app.undo(); 199 | else isUndo = true; 200 | 201 | startAction(); 202 | app.redraw(); 203 | } 204 | else if (isUndo) { 205 | app.undo(); 206 | app.redraw(); 207 | isUndo = false; 208 | } 209 | } 210 | 211 | win.onClose = function () { 212 | if (isUndo) { 213 | app.undo(); 214 | app.redraw(); 215 | isUndo = false; 216 | } 217 | 218 | saveSettings(); 219 | return true; 220 | } 221 | 222 | function saveSettings() { 223 | try{ 224 | var $file = new File(settingFile.folder + settingFile.name), 225 | data = [ 226 | __offsetSlider.value, 227 | __offset.text, 228 | __isKeyObject.value, 229 | __deltaSlider.value, 230 | __delta.text 231 | ].toString(); 232 | 233 | $file.open('w'); 234 | $file.write(data); 235 | $file.close(); 236 | }catch(e){$.errorMessage(e);} 237 | } 238 | 239 | function loadSettings() { 240 | var $file = File(settingFile.folder + settingFile.name); 241 | if ($file.exists) { 242 | try { 243 | $file.open('r'); 244 | var data = $file.read().split('\n'), 245 | $main = data[0].split(','); 246 | __offsetSlider.value = parseInt($main[0]); 247 | __offset.text = $main[1]; 248 | __isKeyObject.value = ($main[2] === 'true'); 249 | __deltaSlider.value = parseInt($main[3]); 250 | __delta.text = $main[4]; 251 | 252 | __keyObject.enabled = __keyObjectTitle.enabled = __isKeyObject.value; 253 | } catch (e) {} 254 | $file.close(); 255 | } 256 | } 257 | 258 | function checkSettingFolder() { 259 | var $folder = new Folder(settingFile.folder); 260 | if (!$folder.exists) $folder.create(); 261 | } 262 | 263 | checkSettingFolder(); 264 | loadSettings(); 265 | 266 | win.center(); 267 | win.show(); -------------------------------------------------------------------------------- /transferSwatches.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ 5 | Name: transferSwatches.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | function LA(obj, callback, reverse) {if (!callback) {if (obj instanceof Array) {return obj;}else {var arr = $.getArr(obj);if (arr === obj) {if ($.isColor(obj)) {return obj;}else {return [obj];}}return arr;}}else if (callback instanceof Function) {var arr = $.getArr(obj);if (arr === obj) {arr = [obj];}if (reverse) {var i = arr.length;while (i--) callback(arr[i], i, arr);}else {for (var i = 0; i < arr.length; i++) callback(arr[i], i, arr);}return arr;}}$.isColor = function (color) {if ((color.typename === 'GradientColor')|| (color.typename === 'PatternColor')|| (color.typename === 'CMYKColor')|| (color.typename === 'SpotColor')|| (color.typename === 'GrayColor')|| (color.typename === 'LabColor')|| (color.typename === 'RGBColor')|| (color.typename === 'NoColor')) {return true;}else {return false;}};$.isArr = function (a) {if ((!a)|| (typeof a === 'string')|| (a.typename === 'Document')|| (a.typename === 'Layer')|| (a.typename === 'PathItem')|| (a.typename === 'GroupItem')|| (a.typename === 'PageItem')|| (a.typename === 'CompoundPathItem')|| (a.typename === 'TextFrame')|| (a.typename === 'TextRange')|| (a.typename === 'GraphItem')|| (a.typename === 'Document')|| (a.typename === 'Artboard')|| (a.typename === 'LegacyTextItem')|| (a.typename === 'NoNNativeItem')|| (a.typename === 'Pattern')|| (a.typename === 'PlacedItem')|| (a.typename === 'PluginItem')|| (a.typename === 'RasterItem')|| (a.typename === 'MeshItem')|| (a.typename === 'SymbolItem')) {return false;}else if (!a.typename && !(a instanceof Array)) {return false;}else {return true;}};$.getArr = function (obj, attr, value, exclude) {var arr = [];function checkExclude (item) {if (exclude !== undefined) {var j = exclude.length;while (j--) if (exclude[j] === item) return true;}return false;}if ($.isArr(obj)) {for (var i = 0; i < obj.length; i++) {if (!checkExclude(obj[i])) {if (attr) {if (value !== undefined) {arr.push(obj[i][attr][value]);}else {arr.push(obj[i][attr]);}}else {arr.push(obj[i]);}}}return arr;}else if (attr) {return obj[attr];}else {return obj;}};$.errorMessage = function (err) {alert(err + '\n' + err.line);};Object.prototype.extend = function (userObject, deep) {try {for (var key in userObject) {if (this.hasOwnProperty(key)) {if (deep&& this[key] instanceof Object&& !(this[key] instanceof Array)&& userObject[key] instanceof Object&& !(userObject[key] instanceof Array)) {this[key].extend(userObject[key], deep);}else this[key] = userObject[key];}}return this;}catch (e) {$.errorMessage('$.objectParser() - error: ' + e);}};Object.prototype.getSwatches = function() {var arr = [], obj = LA(this);for (var i = 0; i < obj.length; i++) {arr = arr.concat(LA(obj[i].swatches));}return arr;};Object.prototype.getSwatchGroups = function() {var arr = [], obj = LA(this);for (var i = 0; i < obj.length; i++) {var length = obj[i].swatchGroups.length;for (var j = 1; j < length; j++) {arr = arr.concat(obj[i].swatchGroups[j]);}}return arr;};Object.prototype.getSwatchGroupsWithSwatches = function() {var groups = this.getSwatchGroups(), arr = [];LA(groups, function (group, i) {arr.push({name: group.name,swatches: group.getAllSwatches()});});return arr;};Object.prototype.getSwatchGroupsOnlySwatches = function() {var groups = this.getSwatchGroups(), arr = [];LA(groups, function (group, i) {arr = arr.concat(group.getAllSwatches());});return arr;}; 12 | Object.prototype.addSwatches = function (obj, property) { 13 | /* 14 | if (obj === 'group') property = { 15 | name : 'Name group', 16 | swatches : [ 17 | { 18 | name : 'Name Swatch', 19 | type : Swatch color type / ' String ', 20 | values : Swatch color values / [ Array ], 21 | color: [Color] / [Object] 22 | } 23 | ], 24 | spots : [ 25 | { 26 | name : 'Name spot color', 27 | type : Spot color type / ' String ', 28 | values : Spot color values / [ Array ], 29 | colorType : ColorModel / ' String ' 30 | color: [Color] / [Object] 31 | } 32 | ] 33 | }, 34 | if (obj === 'swatch') property = { 35 | name : 'Name Swatch', 36 | type : Swatch color type / ' String ', 37 | values : Swatch color values / [ Array ] 38 | color: [Color] / [Object] 39 | } 40 | */ 41 | function addSwatch(doc) { 42 | var collection = []; 43 | if (obj && property instanceof Object) { 44 | if (typeof obj === 'string') { 45 | switch (obj.toLocaleLowerCase()) { 46 | case 'group': 47 | var sg = doc.swatchGroups.add(); 48 | sg.name = property.name || 'Untitled'; 49 | collection = collection.concat(sg); 50 | if (property.swatches) { 51 | if (property.swatches instanceof Object && !(property.swatches instanceof Array)) { 52 | property.swatches = [property.swatches]; 53 | } 54 | if (property.swatches instanceof Array) { 55 | for (var i = 0; i < property.swatches.length; i++) { 56 | var s = (property.swatches[i].isGlobal ? doc.spots.add() : doc.swatches.add()); 57 | s.name = property.swatches[i].name || 'Untitled'; 58 | s.color = property.swatches[i].color || $.color(property.swatches[i].type || 'cmyk', property.swatches[i].values || [0, 0, 0, 0]); 59 | sg.addSwatch(s); 60 | } 61 | } 62 | } 63 | ; break; 64 | case 'swatch': 65 | if (property) { 66 | if (property instanceof Object && !(property instanceof Array)) { 67 | property = [property]; 68 | } 69 | if (property instanceof Array) { 70 | for (var i = 0; i < property.length; i++) { 71 | var s = (property[i].isGlobal ? doc.spots.add() : doc.swatches.add()); 72 | collection = collection.concat(s); 73 | s.name = property[i].name || 'Untitled'; 74 | s.color = property[i].color || $.color(property[i].type || 'cmyk', property[i].values || [0, 0, 0, 0]); 75 | } 76 | } 77 | } 78 | ; break; 79 | } 80 | } 81 | } 82 | else { 83 | return doc; 84 | } 85 | return collection; 86 | } 87 | var arr = [], docs = LA(this); 88 | for (var i = 0; i < docs.length; i++) { 89 | arr = arr.concat(addSwatch(docs[i])); 90 | } 91 | return arr; 92 | }; 93 | Object.prototype.getSwatchesSaveStructure = function (onlySelected) { 94 | var __swatches = { 95 | swatches: [], 96 | groups: [] 97 | }, 98 | activeDoc = activeDocument, 99 | obj = LA(this), 100 | length = obj.length; 101 | 102 | function __getAllSwatches (group, selected) { 103 | return onlySelected ? LA(group.getAllSwatches()).sameItems(selected) : group.getAllSwatches(); 104 | } 105 | 106 | for (var i = 0; i < length; i++) { 107 | var selectedSwatches = obj[i].swatches.getSelected(); 108 | // obj[i].activate(); 109 | LA(obj[i].swatchGroups, function (group, i) { 110 | if (!i) { 111 | __swatches.swatches = __getAllSwatches(group, selectedSwatches); 112 | } 113 | else { 114 | __swatches.groups.push({ 115 | name: group.name, 116 | swatches: __getAllSwatches(group, selectedSwatches) 117 | }); 118 | } 119 | }); 120 | } 121 | // activeDoc.activate(); 122 | return __swatches; 123 | }; 124 | Object.prototype.transferSwatches = function (userOptions) { 125 | var options = { 126 | replace: false 127 | }.extend(userOptions || {}, true); 128 | 129 | var __doc = activeDocument, 130 | __swatches = LA(this).getSwatchesSaveStructure(); 131 | 132 | // without group swatches 133 | LA(__swatches.swatches, function (swatch, i) { 134 | if (swatch.name !== '[Registration]' && swatch.name !== '[None]') { 135 | try { 136 | var swatchOriginal = __doc.swatches.getByName(swatch.name); 137 | if (options.replace) { 138 | swatchOriginal.color = swatch.color; 139 | } 140 | else { 141 | __doc.addSwatches('swatch', { 142 | name: swatch.name + '_' + __swatches.swatches.length + i, 143 | color: swatch.color 144 | }); 145 | } 146 | } 147 | catch (e) { 148 | __doc.addSwatches('swatch', { 149 | name: swatch.name, 150 | color: swatch.color 151 | }); 152 | } 153 | } 154 | }); 155 | function checkName (name, items) { 156 | var x = items.length; 157 | while (x--) if (items[x].name === name) return items[x]; 158 | return false; 159 | } 160 | 161 | // group swatches 162 | if (!options.replace) { 163 | LA(__swatches.groups, function (group, i) { 164 | __doc.addSwatches('group', { 165 | name: group.name, 166 | swatches: group.swatches 167 | }); 168 | }); 169 | } 170 | else { 171 | LA(__swatches.groups, function ($group, i) { 172 | try { 173 | var __group = __doc.swatchGroups.getByName($group.name), 174 | replaceSwatch, $gswatch; 175 | 176 | for (var j = 0; j < $group.swatches.length; j++) { 177 | replaceSwatch = checkName($group.swatches[j].name, __group.getAllSwatches()); 178 | if (replaceSwatch) { 179 | replaceSwatch.color = $group.swatches[j].color; 180 | } 181 | else { 182 | $gswatch = __doc.swatches.add(); 183 | $gswatch.name = $group.swatches[j].name; 184 | $gswatch.color = $group.swatches[j].color; 185 | __group.addSwatch($gswatch); 186 | } 187 | } 188 | } 189 | catch (e) { 190 | __doc.addSwatches('group', { 191 | name: $group.name, 192 | swatches: $group.swatches 193 | }); 194 | } 195 | }); 196 | } 197 | }; 198 | var win = new Window('dialog', 'Transfer swatches \u00A9 www.ladyginpro.ru', undefined); 199 | win.orientation = 'column'; 200 | win.alignChildren = ['fill', 'fill']; 201 | 202 | panel = win.add('panel', undefined, 'Please select a document!'); 203 | var winDocs = panel.add('dropdownlist', [0, 0, 180, 30], $.getArr(app.documents, 'name', undefined, [activeDocument])), 204 | winReplace = panel.add('checkbox', [0, 0, 180, 15], 'Replace the same by name'); 205 | 206 | winDocs.selection = 0; 207 | 208 | var winButtons = win.add('group'); 209 | winButtons.alignChildren = ['fill', 'fill']; 210 | winButtons.margins = [0, 0, 0, 0]; 211 | 212 | var cancel = winButtons.add('button', undefined, 'Cancel'); 213 | cancel.helpTip = 'Press Esc to Close'; 214 | cancel.onClick = function () { win.close(); } 215 | 216 | var ok = winButtons.add('button', [0, 0, 100, 30], 'OK'); 217 | ok.helpTip = 'Press Enter to Run'; 218 | ok.onClick = startAction; 219 | ok.active = true; 220 | 221 | win.center(); 222 | win.show(); 223 | 224 | 225 | function startAction () { 226 | app.documents[winDocs.selection].transferSwatches({ 227 | replace: winReplace.value 228 | }); 229 | win.close(); 230 | } -------------------------------------------------------------------------------- /long_shadow.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ 5 | Name: long_shadow.jsx; 6 | 7 | Copyright (c) 2019 8 | www.ladyginpro.ru 9 | 10 | */ 11 | 12 | $.getUnits = function (val, def) {return 'px,pt,mm,cm,in,pc'.indexOf(val.slice(-2)) > -1 ? val.slice(-2) : def;}; 13 | $.convertUnits = function (obj, b) {if (obj === undefined) {return obj;}if (b === undefined) {b = 'px';}if (typeof obj === 'number') {obj = obj + 'px';}if (typeof obj === 'string') {var unit = $.getUnits(obj),val = parseFloat(obj);if (unit && !isNaN(val)) {obj = val;}else if (!isNaN(val)) {obj = val; unit = 'px';}}if (((unit === 'px') || (unit === 'pt')) && (b === 'mm')) {obj = parseFloat(obj) / 2.83464566929134;}else if (((unit === 'px') || (unit === 'pt')) && (b === 'cm')) {obj = parseFloat(obj) / (2.83464566929134 * 10);}else if (((unit === 'px') || (unit === 'pt')) && (b === 'in')) {obj = parseFloat(obj) / 72;}else if ((unit === 'mm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134;}else if ((unit === 'mm') && (b === 'cm')) {obj = parseFloat(obj) * 10;}else if ((unit === 'mm') && (b === 'in')) {obj = parseFloat(obj) / 25.4;}else if ((unit === 'cm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134 * 10;}else if ((unit === 'cm') && (b === 'mm')) {obj = parseFloat(obj) / 10;}else if ((unit === 'cm') && (b === 'in')) {obj = parseFloat(obj) * 2.54;}else if ((unit === 'in') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 72;}else if ((unit === 'in') && (b === 'mm')) {obj = parseFloat(obj) * 25.4;}else if ((unit === 'in') && (b === 'cm')) {obj = parseFloat(obj) * 25.4;}return parseFloat(obj);}; 14 | 15 | 16 | var scriptName = 'long_shadow', 17 | copyright = ' \u00A9 www.ladyginpro.ru', 18 | settingFile = { 19 | name: scriptName + '__setting.json', 20 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 21 | } 22 | __items = (function () { 23 | var arr = [], l = selection.length; 24 | for (var n = 0; n < l; n++) { 25 | arr.push(selection[n]); 26 | } 27 | return arr; 28 | }()); 29 | 30 | function shadow (items, options, originalItem, compoundGroup) { 31 | options = options || {}; 32 | 33 | function setShadow (item) { 34 | var shadowPath, 35 | parent = (originalItem || item).parent; 36 | 37 | var group = (compoundGroup || parent.groupItems.add()), 38 | p = item.pathPoints, 39 | n = p.length; 40 | 41 | 42 | for (var i = 0, j = 1; i < n; i++, j++) { 43 | shadowPath = group.pathItems.add(); 44 | 45 | if (i === n - 1) { 46 | if (n === 2) break; 47 | j = 0; 48 | } 49 | 50 | shadowPath.setEntirePath([ 51 | // 1 line 52 | [ 53 | p[i].anchor[0], 54 | p[i].anchor[1] 55 | ], 56 | [ 57 | p[j].anchor[0], 58 | p[j].anchor[1] 59 | ], 60 | // 2 line 61 | [ 62 | p[j].anchor[0], 63 | p[j].anchor[1] 64 | ], 65 | [ 66 | (p[j].anchor[0] - p[j].anchor[0]) * Math.cos(angle) - (p[j].anchor[1] + options.size - p[j].anchor[1]) * Math.sin(angle) + p[j].anchor[0], 67 | (p[j].anchor[0] - p[j].anchor[0]) * Math.sin(angle) + (p[j].anchor[1] + options.size - p[j].anchor[1]) * Math.cos(angle) + p[j].anchor[1] 68 | ], 69 | // 3 line 70 | [ 71 | (p[i].anchor[0] - p[i].anchor[0]) * Math.cos(angle) - (p[i].anchor[1] + options.size - p[i].anchor[1]) * Math.sin(angle) + p[i].anchor[0], 72 | (p[i].anchor[0] - p[i].anchor[0]) * Math.sin(angle) + (p[i].anchor[1] + options.size - p[i].anchor[1]) * Math.cos(angle) + p[i].anchor[1] 73 | ] 74 | ]) 75 | 76 | shadowPath.closed = true; 77 | } 78 | 79 | // var copy = (originalItem || item).duplicate(); 80 | // if (copy.typename === 'CompoundPathItem') { 81 | // copy.moveToBeginning(group); 82 | // } 83 | // copy.selected = false; 84 | // copy.position = [ 85 | // (copy.position[0] - copy.position[0]) * Math.cos(angle) - (copy.position[1] + options.size - copy.position[1]) * Math.sin(angle) + copy.position[0], 86 | // (copy.position[0] - copy.position[0]) * Math.sin(angle) + (copy.position[1] + options.size - copy.position[1]) * Math.cos(angle) + copy.position[1] 87 | // ]; 88 | // copy.moveToBeginning(group); 89 | 90 | group.move((originalItem || item), ElementPlacement.PLACEAFTER); 91 | group.opacity = 50; 92 | } 93 | 94 | if (items.typename && items.typename.slice(-1) !== 's') { 95 | items = [items]; 96 | } 97 | 98 | options.size = (typeof options.size === 'number' ? options.size : 600); 99 | options.angle = (typeof options.angle === 'number' ? options.angle : 45); 100 | 101 | var l = items.length, 102 | angle = (180 + options.angle) * Math.PI / 180; 103 | 104 | for (var x = 0; x < l; x++) { 105 | if (items[x].typename === 'PathItem') { 106 | setShadow(items[x]); 107 | if (options.removeItem) { 108 | items[x].remove(); 109 | } 110 | } else if (items[x].typename === 'CompoundPathItem') { 111 | var __compoundGroup = items[x].parent.groupItems.add(); 112 | __compoundGroup.move(items[x], ElementPlacement.PLACEAFTER); 113 | shadow(items[x].pathItems, options, originalItem || items[x], __compoundGroup); 114 | } else if (items[x].typename === 'GroupItem') { 115 | shadow(items[x].pageItems, options); 116 | } else if (items[x].typename === 'TextFrame') { 117 | options.removeItem = true; 118 | shadow(items[x].duplicate(items[x], ElementPlacement.PLACEAFTER).createOutline(), options); 119 | options.removeItem = false; 120 | } 121 | } 122 | } 123 | 124 | function inputNumberEvents (ev, _input, min, max, callback){ 125 | var step, 126 | round = false, 127 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 128 | _value = parseFloat(_input.text), 129 | _valueOld = _value, 130 | units = (',px,pt,mm,cm,in,eg,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 131 | 132 | if (units === 'eg') units = 'd' + units; 133 | 134 | min = (min === undefined ? 0 : min); 135 | max = (max === undefined ? Infinity : max); 136 | step = (ev.shiftKey && ev.ctrlKey ? 10 137 | : (ev.ctrlKey && !ev.altKey ? .1 138 | : (ev.ctrlKey && ev.altKey ? .5 139 | : (ev.altKey ? .2 : 1) 140 | ) 141 | ) 142 | ); 143 | if (ev.shiftKey && !ev.ctrlKey) { 144 | round = true; 145 | step = 10; 146 | } 147 | 148 | if (isNaN(_value)) { 149 | _input.text = min; 150 | } 151 | else { 152 | if (round) { 153 | if (_dir === 'u') { 154 | _value = Math.ceil(_value / 10) * 10; 155 | if (_value === _valueOld) { 156 | _value += step; 157 | } 158 | } else if (_dir === 'd') { 159 | _value = Math.floor(_value / 10) * 10; 160 | if (_value === _valueOld) { 161 | _value -= step; 162 | } 163 | } else { 164 | _value = false; 165 | } 166 | } 167 | else { 168 | _value = ( (_dir === 'u') ? _value + step : ((_dir === 'd') ? _value - step : false) ); 169 | } 170 | 171 | if (_value !== false) { 172 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 173 | _input.text = _value; 174 | if (callback instanceof Function) callback(_value, _input, min, max, units); 175 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 176 | } 177 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 178 | } 179 | } 180 | 181 | var isUndo = false, 182 | win = new Window('dialog', 'Long shadow \u00A9 www.ladyginpro.ru'); 183 | 184 | win.alignChildren = 'fill'; 185 | 186 | with (panel = win.add('panel')) { 187 | alignChildren = ['fill', 'bottom']; 188 | 189 | with (add('group')) { 190 | add('statictext', undefined, 'Angle:'); 191 | var __sliderInput = add('edittext', [0, 0, 65, 25], '45 deg'); 192 | var __slider = add('slider', [0, 0, 200, 15], 45, 0, 360); 193 | 194 | __sliderInput.active = true; 195 | __slider.onChanging = function (e) { __sliderInput.text = Math.round(this.value) + ' deg'; } 196 | __slider.onChange = function (e) { previewStart(); } 197 | __sliderInput.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __slider.minvalue, __slider.maxvalue); }); 198 | __sliderInput.addEventListener('keyup', function (e) { __slider.value = Math.round(this.text); previewStart(); }); 199 | } 200 | 201 | with (add('group')) { 202 | add('statictext', undefined, 'Size:'); 203 | var __sliderInputSize = add('edittext', [0, 0, 75, 25], '300 px'); 204 | var __sliderSize = add('slider', [0, 0, 200, 15], 300, 0, 1000); 205 | 206 | __sliderInputSize.active = true; 207 | __sliderSize.onChanging = function (e) { __sliderInputSize.text = Math.round(this.value) + ' px'; } 208 | __sliderSize.onChange = function (e) { previewStart(); } 209 | __sliderInputSize.addEventListener('keydown', function (e) { inputNumberEvents(e, this, __sliderSize.minvalue, __sliderSize.maxvalue * 5); }); 210 | __sliderInputSize.addEventListener('keyup', function (e) { __sliderSize.value = Math.round(this.text); previewStart(); }); 211 | } 212 | 213 | with (win.add('group')) { 214 | orientation = 'row'; 215 | alignChildren = ['fill', 'fill']; 216 | 217 | var preview = add('checkbox', undefined, 'Preview'), 218 | cancelBtn = add('button', undefined, 'Cancel'), 219 | applyBtn = add('button', undefined, 'Ok', { name: 'ok' }); 220 | 221 | preview.value = true; 222 | 223 | preview.onClick = function() { previewStart(); } 224 | cancelBtn.onClick = function() { win.close(); } 225 | applyBtn.onClick = function() { 226 | if (preview.value && isUndo) { 227 | isUndo = false; 228 | win.close(); 229 | } 230 | else { 231 | app.undo(); 232 | startAction(); 233 | isUndo = false; 234 | win.close(); 235 | } 236 | } 237 | } 238 | 239 | } 240 | 241 | function startAction() { 242 | shadow(__items, { 243 | angle: __slider.value, 244 | size: $.convertUnits(__sliderInputSize.text, 'px') 245 | }); 246 | } 247 | 248 | function previewStart() { 249 | try { 250 | if (preview.value) { 251 | if (isUndo) { 252 | app.undo(); 253 | } 254 | else isUndo = true; 255 | 256 | startAction(); 257 | app.redraw(); 258 | } 259 | else if (isUndo) { 260 | app.undo(); 261 | app.redraw(); 262 | isUndo = false; 263 | } 264 | } catch (err) { 265 | alert(err + '\n' + err.line); 266 | } 267 | } 268 | 269 | 270 | win.onClose = function () { 271 | try { 272 | if (isUndo) { 273 | app.undo(); 274 | app.redraw(); 275 | isUndo = false; 276 | items = null; 277 | } 278 | } catch (e) {} 279 | saveSettings(); 280 | } 281 | 282 | 283 | function saveSettings() { 284 | try{ 285 | var $file = new File(settingFile.folder + settingFile.name), 286 | data = [ 287 | __sliderInput.text, 288 | __sliderInputSize.text, 289 | preview.value 290 | ].toString(); 291 | 292 | $file.open('w'); 293 | $file.write(data); 294 | $file.close(); 295 | }catch(e){$.errorMessage(e);} 296 | } 297 | 298 | function loadSettings() { 299 | var $file = File(settingFile.folder + settingFile.name); 300 | if ($file.exists) { 301 | try { 302 | $file.open('r'); 303 | var data = $file.read().split('\n'), 304 | $main = data[0].split(','); 305 | __sliderInput.text = $main[0]; 306 | __sliderInputSize.text = $main[1]; 307 | preview.value = ($main[2] === 'true'); 308 | 309 | __slider.value = parseInt($main[0]); 310 | __sliderSize.value = parseInt($main[1]); 311 | } catch (e) {} 312 | $file.close(); 313 | } 314 | } 315 | 316 | function checkSettingFolder() { 317 | var $folder = new Folder(settingFile.folder); 318 | if (!$folder.exists) $folder.create(); 319 | } 320 | 321 | checkSettingFolder(); 322 | loadSettings(); 323 | 324 | 325 | 326 | if (__items.length) { 327 | if (preview.value) { 328 | previewStart(); 329 | isUndo = preview.value; 330 | } 331 | 332 | win.center(); 333 | win.show(); 334 | } -------------------------------------------------------------------------------- /harmonizer.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Program version: Adobe Illustrator CS5+ 4 | Name: harmonizer.jsx; 5 | 6 | Author: Alexander Ladygin, email: i@ladygin.pro 7 | 8 | Copyright (c) 2018 9 | www.ladyginpro.ru 10 | 11 | */ 12 | 13 | var scriptName = 'Harmonizer', 14 | settingFile = { 15 | name: scriptName + '__setting.json', 16 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 17 | }, 18 | useClippingMask = true; 19 | 20 | var isUndo = false, 21 | win = new Window('dialog', scriptName + ' \u00A9 www.ladyginpro.ru', undefined); 22 | win.orientation = 'column'; 23 | win.alignChildren = 'fill'; 24 | 25 | var panel = win.add('panel', undefined, 'Harmonizer setting'); 26 | panel.orientation = 'column'; 27 | panel.alignChildren = 'fill'; 28 | panel.margins = 20; 29 | 30 | var groupColumns = panel.add('group'); 31 | groupColumns.orientation = 'row'; 32 | groupColumns.alignChildren = 'center'; 33 | var captionColumns = groupColumns.add('statictext', undefined, 'Columns:'), 34 | valueColumns = groupColumns.add('edittext', [0, 0, 110, 25], 4); 35 | 36 | var groupGutter = panel.add('group'); 37 | groupGutter.orientation = 'row'; 38 | groupGutter.alignChildren = ['fill', 'fill']; 39 | 40 | var groupGutterX = groupGutter.add('group'); 41 | groupGutterX.orientation = 'column'; 42 | groupGutterX.alignChildren = 'left'; 43 | var captionGutterX = groupGutterX.add('statictext', undefined, 'Gutter X:'), 44 | valueGutterX = groupGutterX.add('edittext', [0, 0, 80, 25], 0), 45 | positionX = groupGutterX.add('dropdownlist', [0, 0, 80, 25], ['Left', 'Center', 'Right']); 46 | positionX.selection = 1; 47 | 48 | var groupGutterY = groupGutter.add('group'); 49 | groupGutterY.orientation = 'column'; 50 | groupGutterY.alignChildren = 'left'; 51 | var captionGutterY = groupGutterY.add('statictext', undefined, 'Gutter Y:'), 52 | valueGutterY = groupGutterY.add('edittext', [0, 0, 80, 25], 0), 53 | positionY = groupGutterY.add('dropdownlist', [0, 0, 80, 25], ['Top', 'Middle', 'Bottom']); 54 | positionY.selection = 1; 55 | 56 | var groupCheckbox = panel.add('group'); 57 | groupCheckbox.orientation = 'row'; 58 | var toGroupCheckbox = groupCheckbox.add('checkbox', undefined, 'Group'), 59 | randomOrderCheckbox = groupCheckbox.add('checkbox', [0, 0, 100, 20], 'Random order'); 60 | randomOrderCheckbox.onClick = previewStart; 61 | 62 | // var sortReverseGroup = panel.add('group'); 63 | // groupCheckbox.orientation = 'row'; 64 | 65 | with (panel.add('group')) { 66 | orientation = 'column'; 67 | alignChildren = ['fill', 'fill']; 68 | 69 | with (add('group')) { 70 | orientation = 'row'; 71 | alignChildren = ['fill', 'fill']; 72 | 73 | add('statictext', undefined, 'Sort items by:'); 74 | var reverseOrder = add('checkbox', undefined, 'Reverse order'); 75 | } 76 | with (add('group')) { 77 | orientation = 'row'; 78 | alignChildren = ['fill', 'fill']; 79 | 80 | var sortByY = add('radiobutton', undefined, 'Y'), 81 | sortByX = add('radiobutton', undefined, 'X'), 82 | sortByS = add('radiobutton', undefined, 'S'), 83 | sortByW = add('radiobutton', undefined, 'W'), 84 | sortByH = add('radiobutton', undefined, 'H'); 85 | sortByY.helpTip = 'Sort by Top to Bottom'; 86 | sortByX.helpTip = 'Sort by Left to Right'; 87 | sortByS.helpTip = 'Sort by Size (width + height) max to min'; 88 | sortByW.helpTip = 'Sort by Width max to min'; 89 | sortByH.helpTip = 'Sort by Height min to max'; 90 | } 91 | } 92 | 93 | 94 | sortByY.onClick = sortByX.onClick = sortByW.onClick = sortByH.onClick = sortByS.onClick = reverseOrder.onClick = previewStart; 95 | 96 | var preview = win.add('checkbox', undefined, 'Preview'); 97 | 98 | var winButtons = win.add('group'); 99 | winButtons.orientation = 'row'; 100 | winButtons.alignChildren = ['fill', 'fill']; 101 | winButtons.margins = 0; 102 | 103 | var cancel = winButtons.add('button', undefined, 'Cancel'); 104 | cancel.helpTip = 'Press Esc to Close'; 105 | cancel.onClick = function () { win.close(); } 106 | 107 | var ok = winButtons.add('button', undefined, 'OK'); 108 | ok.helpTip = 'Press Enter to Run'; 109 | ok.onClick = function (e) { 110 | if (preview.value && isUndo) app.undo(); 111 | startAction(); 112 | if (toGroupCheckbox.value) toGroupItems(); 113 | isUndo = false; 114 | win.close(); 115 | }; 116 | ok.active = true; 117 | 118 | function handle_key(key, control, min){var step;if(key.shiftKey){step = 10;}else if(key.ctrlKey){step = .1}else{step = 1}switch (key.keyName){case "Up": control.text = String(Number(parseFloat(control.text))+step); break;case "Down": control.text = String(Number(parseFloat(control.text))-step);}if((control.text === 'NaN') || (control.text <= 0)){control.text = min}} 119 | valueColumns.addEventListener('keydown', function (e) { handle_key(e, this, 1); previewStart(); }); 120 | valueGutterX.addEventListener('keydown', function (e) { 121 | if (e.ctrlKey && e.keyName === 'Right') { valueGutterY.text = this.text; } 122 | else handle_key(e, this, 0); 123 | previewStart(); 124 | }); 125 | valueGutterY.addEventListener('keydown', function (e) { 126 | if (e.ctrlKey && e.keyName === 'Left') { valueGutterX.text = this.text; } 127 | else handle_key(e, this, 0); 128 | previewStart(); 129 | }); 130 | preview.onClick = function (e) { previewStart(); }; 131 | 132 | function toGroupItems() { 133 | var items = selection, 134 | i = items.length, 135 | target = items[0].parent, 136 | __group = target.groupItems.add(); 137 | 138 | while (i--) { 139 | items[i].moveToBeginning(__group); 140 | } 141 | 142 | return __group; 143 | } 144 | 145 | function boundsClippingMask (item, prop) { 146 | if (useClippingMask && item.typename === 'GroupItem' && item.clipped) { 147 | var i = item.pageItems.length; 148 | while (i-- > -1) { 149 | if (item.pageItems[i].clipping) { 150 | return (prop === 'item' ? item.pageItems[i] : item.pageItems[i][prop || 'geometricBounds']); 151 | } 152 | } 153 | } 154 | return (prop === 'item' ? item : item[prop]); 155 | } 156 | 157 | function selectionBounds (bounds) { 158 | bounds = (typeof bounds === 'string' && bounds.length && bounds.slice(0,1) === 'v' ? 'visibleBounds' : 'geometricBounds'); 159 | 160 | var arr = selection, x = [], 161 | y = [], w = [], h = [], 162 | size = [[], []], 163 | i = arr.length, 164 | bnds = [], 165 | __item; 166 | 167 | while (i--) { 168 | __item = boundsClippingMask(arr[i], 'item'); 169 | bnds = __item[bounds]; 170 | x.push(bnds[0]); 171 | y.push(bnds[1]); 172 | w.push(bnds[2]); 173 | h.push(bnds[3]); 174 | size[0].push(bnds[2] - bnds[0]); 175 | size[1].push(bnds[1] - bnds[3]); 176 | }; 177 | 178 | return [Math.min.apply(null, x), Math.max.apply(null, y), Math.max.apply(null, w), Math.min.apply(null, h), Math.max.apply(null, size[0]), Math.max.apply(null, size[1])]; 179 | } 180 | 181 | Array.prototype.randomArray = function() { 182 | var ix = this.length, ti, $i; 183 | while (0 !== ix) { 184 | $i = Math.floor(Math.random() * ix); 185 | ix -= 1; ti = this[ix]; 186 | this[ix] = this[$i]; 187 | this[$i] = ti; 188 | } 189 | return this; 190 | } 191 | 192 | function startAction() { 193 | var bounds = 'visibleBounds', 194 | items = (sortByY.value ? selection.sort(function (a, b) { 195 | var a_bounds = boundsClippingMask(a, bounds), 196 | b_bounds = boundsClippingMask(b, bounds); 197 | return b_bounds[1] - a_bounds[1]; 198 | }) : (sortByX.value ? selection.sort(function (a, b) { 199 | var a_bounds = boundsClippingMask(a, bounds), 200 | b_bounds = boundsClippingMask(b, bounds); 201 | return a_bounds[0] - b_bounds[0]; 202 | }) : (sortByS.value ? selection.sort(function (a, b) { 203 | var _a = boundsClippingMask(a, 'item'), 204 | _b = boundsClippingMask(b, 'item'); 205 | return (_b.width + _b.height) - (_a.width + _a.height); 206 | }) : (sortByW.value ? selection.sort(function (a, b) { 207 | var _a = boundsClippingMask(a, 'item'), 208 | _b = boundsClippingMask(b, 'item'); 209 | return _b.width - _a.width; 210 | }) : (sortByH.value ? selection.sort(function (a, b) { 211 | var _a = boundsClippingMask(a, 'item'), 212 | _b = boundsClippingMask(b, 'item'); 213 | return _b.height - _a.height; 214 | }) : selection))))); 215 | if (randomOrderCheckbox.value) items.randomArray(); 216 | if (reverseOrder.value) items.reverse(); 217 | var l = items.length, __rows = 0, 218 | gutter = { 219 | x: parseFloat(valueGutterX.text), 220 | y: parseFloat(valueGutterY.text) 221 | }, 222 | __posXValue = positionX.selection.text.toLowerCase(), 223 | __posYValue = positionY.selection.text.toLowerCase(), 224 | columns = parseInt(valueColumns.text), 225 | bnds = selectionBounds(bounds); 226 | 227 | function __align (__pos, __bnds) { 228 | if (__pos === 'middle') return (bnds[5] - (__bnds[1] - __bnds[3])) / 2; 229 | else if (__pos === 'bottom') return bnds[5] - (__bnds[1] - __bnds[3]); 230 | else if (__pos === 'center') return (bnds[4] - (__bnds[2] - __bnds[0])) / 2; 231 | else if (__pos === 'right') return bnds[4] - (__bnds[2] - __bnds[0]); 232 | else return 0; 233 | } 234 | 235 | if (l > 1) { 236 | var __item, __bnds; 237 | for (var i = j = 0; i < l; i++, j++) { 238 | if (j === columns) { __rows++; j = 0; } 239 | 240 | __item = boundsClippingMask(items[i], 'item'); 241 | __bnds = boundsClippingMask(items[i], bounds); 242 | 243 | if (__item !== items[i]) { 244 | items[i].left = bnds[0] + (bnds[4] + gutter.x) * j + __align(__posXValue, __bnds) + (items[i].geometricBounds[0] - __item.geometricBounds[0]); 245 | items[i].top = bnds[1] - (bnds[5] + gutter.y) * __rows - __align(__posYValue, __bnds) + (items[i].geometricBounds[1] - __item.geometricBounds[1]); 246 | } else { 247 | items[i].left = bnds[0] + (bnds[4] + gutter.x) * j + __align(__posXValue, __bnds); 248 | items[i].top = bnds[1] - (bnds[5] + gutter.y) * __rows - __align(__posYValue, __bnds); 249 | } 250 | } 251 | } 252 | else { 253 | isUndo = false; 254 | } 255 | } 256 | 257 | 258 | function previewStart() { 259 | if (preview.value) { 260 | if (isUndo) app.undo(); 261 | else isUndo = true; 262 | 263 | startAction(); 264 | app.redraw(); 265 | } 266 | else if (isUndo) { 267 | app.undo(); 268 | app.redraw(); 269 | isUndo = false; 270 | } 271 | } 272 | 273 | // preview 274 | valueColumns.addEventListener('change', function (e) { previewStart(); }); 275 | valueGutterY.addEventListener('change', function (e) { previewStart(); }); 276 | valueGutterX.addEventListener('change', function (e) { previewStart(); }); 277 | positionX.addEventListener( 'change', function (e) { previewStart(); }); 278 | positionY.addEventListener( 'change', function (e) { previewStart(); }); 279 | 280 | 281 | function saveSettings() { 282 | var $file = new File(settingFile.folder + settingFile.name), 283 | data = [ 284 | valueColumns.text, 285 | valueGutterX.text, 286 | positionX.selection.index, 287 | valueGutterY.text, 288 | positionY.selection.index, 289 | toGroupCheckbox.value, 290 | randomOrderCheckbox.value, 291 | sortByY.value, 292 | reverseOrder.value, 293 | sortByX.value, 294 | sortByW.value, 295 | sortByH.value, 296 | sortByS.value 297 | ].toString(); 298 | 299 | $file.open('w'); 300 | $file.write(data); 301 | $file.close(); 302 | } 303 | 304 | function loadSettings() { 305 | var $file = File(settingFile.folder + settingFile.name); 306 | if ($file.exists) { 307 | try { 308 | $file.open('r'); 309 | var data = $file.read().split('\n'), 310 | $main = data[0].split(','); 311 | valueColumns.text = $main[0]; 312 | valueGutterX.text = $main[1]; 313 | positionX.selection = parseInt($main[2]); 314 | valueGutterY.text = $main[3]; 315 | positionY.selection = parseInt($main[4]); 316 | toGroupCheckbox.value = ($main[5] === 'true'); 317 | randomOrderCheckbox.value = ($main[6] === 'true'); 318 | sortByY.value = ($main[7] === 'true'); 319 | reverseOrder.value = ($main[8] === 'true'); 320 | sortByX.value = ($main[9] === 'true'); 321 | sortByW.value = ($main[10] === 'true'); 322 | sortByH.value = ($main[11] === 'true'); 323 | sortByS.value = ($main[12] === 'true'); 324 | } catch (e) {} 325 | $file.close(); 326 | } 327 | } 328 | 329 | win.onClose = function () { 330 | if (isUndo) { 331 | app.undo(); 332 | app.redraw(); 333 | isUndo = false; 334 | } 335 | 336 | saveSettings(); 337 | return true; 338 | } 339 | 340 | function checkSettingFolder() { 341 | var $folder = new Folder(settingFile.folder); 342 | if (!$folder.exists) $folder.create(); 343 | } 344 | 345 | checkSettingFolder(); 346 | loadSettings(); 347 | win.center(); 348 | win.show(); -------------------------------------------------------------------------------- /rich_glitch.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ 5 | Name: rich_glitch.jsx; 6 | 7 | Copyright (c) 2019 8 | www.ladyginpro.ru 9 | 10 | */ 11 | 12 | $.errorMessage = function (err) {alert(err + '\n' + err.line);}; 13 | $.forEach = function (items, callback) { var l = items.length; for (var i = 0; i < l; i++) { callback(items[i], i, items); } return items; } 14 | Object.prototype.extend = function (userObject, deep) {try {for (var key in userObject) {if (this.hasOwnProperty(key)) {if (deep&& this[key] instanceof Object&& !(this[key] instanceof Array)&& userObject[key] instanceof Object&& !(userObject[key] instanceof Array)) {this[key].extend(userObject[key], deep);}else this[key] = userObject[key];}}return this;}catch (e) {$.errorMessage('$.objectParser() - error: ' + e);}}; 15 | $.toArr = function (classCollection, callback) {var arr = [], l = classCollection.length;if (l > 0) {for (var i = 0; i < l; i++) {arr.push(classCollection[i]);}}if (callback instanceof Function) return callback(arr);return arr;} 16 | Array.prototype.removeAll = function() { var i = this.length; if (i > 0) while (i--) this[i].remove(); return this; } 17 | 18 | var scriptName = 'rich_glitch', 19 | copyright = ' \u00A9 www.ladyginpro.ru', 20 | settingFile = { 21 | name: scriptName + '__setting.json', 22 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 23 | }, 24 | isUndo = false, 25 | $items = selection; 26 | 27 | 28 | function inputNumberEvents (ev, _input, min, max, callback){ 29 | var step, 30 | round = false, 31 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 32 | _value = parseFloat(_input.text), 33 | _valueOld = _value, 34 | units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 35 | 36 | min = (min === undefined ? 0 : min); 37 | max = (max === undefined ? Infinity : max); 38 | step = (ev.shiftKey && ev.ctrlKey ? 10 39 | : (ev.ctrlKey && !ev.altKey ? .1 40 | : (ev.ctrlKey && ev.altKey ? .5 41 | : (ev.altKey ? .2 : 1) 42 | ) 43 | ) 44 | ); 45 | if (ev.shiftKey && !ev.ctrlKey) { 46 | round = true; 47 | step = 10; 48 | } 49 | 50 | if (isNaN(_value)) { 51 | _input.text = min; 52 | } else { 53 | if (round) { 54 | if (_dir === 'u') { 55 | _value = Math.ceil(_value / 10) * 10; 56 | if (_value === _valueOld) _value += step; 57 | } else if (_dir === 'd') { 58 | _value = Math.floor(_value / 10) * 10; 59 | if (_value === _valueOld) _value -= step; 60 | } else { 61 | _value = false; 62 | } 63 | } else { 64 | _value = ( (_dir === 'u') ? _value + step : ((_dir === 'd') ? _value - step : false) ); 65 | } 66 | 67 | if (_value !== false) { 68 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 69 | _input.text = _value; 70 | 71 | if (callback instanceof Function) { 72 | callback(_value, _input, min, max, units); 73 | } else if (units) { 74 | _input.text = parseFloat(_input.text) + ' ' + units; 75 | } 76 | } else if (units) { 77 | _input.text = parseFloat(_input.text) + ' ' + units; 78 | } 79 | } 80 | } 81 | 82 | function rvbn (min, max) { 83 | // random value between numbers 84 | return min + Math.floor(Math.random() * (max - min)); 85 | } 86 | 87 | function ungroup (group) { 88 | var i = group.pageItems.length; 89 | if (i > 0) while (i--) group.pageItems[i].moveBefore(group); 90 | group.remove(); 91 | } 92 | 93 | function rich_glitch (items, userOptions) { 94 | var options = { 95 | fragments: 20, 96 | offsetX: 10, 97 | rotate: 10, 98 | offsetY: 1, 99 | direction: 'x', 100 | levels: 2, // max 5 101 | removeOriginal: false // do not use with preview 102 | }.extend(userOptions || {}); 103 | 104 | var itemsCollection = []; 105 | 106 | options.fragments = (options.fragments > 0 ? options.fragments : 5) + 1; 107 | options.direction = ((options.direction !== 'x' && options.direction !== 'y') ? 'x' : options.direction); 108 | 109 | function createGrid (item) { 110 | var rect, 111 | copyItem = item.duplicate(item, ElementPlacement.PLACEAFTER), 112 | bnds = copyItem.visibleBounds, 113 | $w = bnds[2] - bnds[0], 114 | $h = bnds[1] - bnds[3], 115 | gGroup = copyItem.parent.groupItems.add(), 116 | $fragmentSize = (options.direction === 'x' ? $h : $w) / options.fragments; 117 | 118 | gGroup.move(copyItem, ElementPlacement.PLACEAFTER); 119 | 120 | for (var i = 0; i < options.fragments; i++) { 121 | rect = gGroup.pathItems.rectangle( 122 | bnds[1] - (options.direction === 'x' ? $fragmentSize * i : 0), 123 | bnds[0] + (options.direction === 'x' ? 0 : $fragmentSize * i), 124 | (options.direction === 'x' ? $w : $fragmentSize), 125 | (options.direction === 'x' ? $fragmentSize : $h) 126 | ); 127 | 128 | rect.filled = rect.stroked = false; 129 | } 130 | 131 | copyItem.move(gGroup, ElementPlacement.PLACEATEND); 132 | itemsCollection.push(gGroup); 133 | 134 | if (options.removeOriginal) item.remove(); 135 | else item.hidden = true; 136 | } 137 | 138 | function setOffset (item) { 139 | item.left += rvbn(options.offsetX * -1, options.offsetX); 140 | item.top -= rvbn(options.offsetY * -1, options.offsetY); 141 | // item.rotate(options.rotate, true, true, true, true); 142 | } 143 | 144 | function createOffset (objs, isSetOffset) { 145 | var n = objs.length; 146 | for (var j = 0; j < n; j++) { 147 | if (isSetOffset) { 148 | setOffset(objs[j]); 149 | } else if (!objs[j].typename) { 150 | createOffset(objs[j]); 151 | } else { 152 | createOffset(objs[j].pageItems, true); 153 | } 154 | } 155 | } 156 | 157 | function getDuplicates (objs) { 158 | var arr = [], l = objs.length; 159 | for (var z = 0; z < l; z++) { 160 | arr.push(objs[z].duplicate(objs[i], ElementPlacement.PLACEAFTER)); 161 | } 162 | return arr; 163 | } 164 | 165 | var l = items.length; 166 | for (var n = 0; n < l; n++) { 167 | createGrid(items[n]); 168 | } 169 | 170 | if (itemsCollection.length) { 171 | selection = itemsCollection; 172 | 173 | app.executeMenuCommand('Live Pathfinder Divide'); 174 | app.executeMenuCommand('expandStyle'); 175 | 176 | var levelsCollection = [selection]; 177 | for (var x = 0; x < options.levels + 1; x++) { 178 | if (x) levelsCollection.push(getDuplicates(selection)); 179 | } 180 | createOffset(levelsCollection); 181 | selection = null; 182 | } 183 | } 184 | 185 | var win = new Window('dialog', 'Rich Glitch' + copyright), 186 | sWidth = 120; 187 | 188 | with (win.add('panel')) { 189 | alignChildren = 'fill'; 190 | 191 | with (add('group')) { 192 | orientation = 'row'; 193 | alignChildren = 'fill'; 194 | 195 | add('statictext', undefined, 'Fragments:'); 196 | var __fragmentsSlider = add('slider', [0, 0, sWidth, 15], 10, 1, 40); 197 | __fragmentsSlider.maximumSize = [1000, 15]; 198 | __fragmentsSlider.onChanging = function (e) { __fragments.text = Math.round(this.value); } 199 | __fragmentsSlider.onChange = function (e) { previewStart(); } 200 | var __fragments = add('edittext', [0, 0, 50, 25], 10); 201 | __fragments.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 1, Infinity); __fragmentsSlider.value = Math.round(this.text); }); 202 | __fragments.addEventListener('keyup', function (e) { previewStart(); }); 203 | } 204 | // with (add('group')) { 205 | // orientation = 'row'; 206 | // alignChildren = 'fill'; 207 | 208 | // add('statictext', undefined, 'Rotate:'); 209 | // var __rotateSlider = add('slider', [0, 0, sWidth + 24, 15], 0, 0, 360); 210 | // __rotateSlider.maximumSize = [1000, 15]; 211 | // __rotateSlider.onChanging = function (e) { __rotate.text = Math.round(this.value); } 212 | // __rotateSlider.onChange = function (e) { previewStart(); } 213 | // var __rotate = add('edittext', [0, 0, 50, 25], 0); 214 | // __rotate.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 0, 360); __rotateSlider.value = Math.round(this.text); }); 215 | // __rotate.addEventListener('keyup', function (e) { previewStart(); }); 216 | // } 217 | with (add('group')) { 218 | orientation = 'row'; 219 | alignChildren = 'fill'; 220 | 221 | add('statictext', undefined, 'Offset X:'); 222 | var __offsetXSlider = add('slider', [0, 0, sWidth + 15, 15], 0, -100, 100); 223 | __offsetXSlider.maximumSize = [1000, 15]; 224 | __offsetXSlider.onChanging = function (e) { __offsetX.text = Math.round(this.value); } 225 | __offsetXSlider.onChange = function (e) { previewStart(); } 226 | var __offsetX = add('edittext', [0, 0, 50, 25], 0); 227 | __offsetX.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 100*-100, 100*100); __offsetXSlider.value = Math.round(this.text); }); 228 | __offsetX.addEventListener('keyup', function (e) { previewStart(); }); 229 | } 230 | with (add('group')) { 231 | orientation = 'row'; 232 | alignChildren = 'fill'; 233 | 234 | add('statictext', undefined, 'Offset Y:'); 235 | var __offsetYSlider = add('slider', [0, 0, sWidth + 15, 15], 0, -100, 100); 236 | __offsetYSlider.maximumSize = [1000, 15]; 237 | __offsetYSlider.onChanging = function (e) { __offsetY.text = Math.round(this.value); } 238 | __offsetYSlider.onChange = function (e) { previewStart(); } 239 | var __offsetY = add('edittext', [0, 0, 50, 25], 0); 240 | __offsetY.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 100*-100, 100*100); __offsetYSlider.value = Math.round(this.text); }); 241 | __offsetY.addEventListener('keyup', function (e) { previewStart(); }); 242 | } 243 | with (add('group')) { 244 | orientation = 'row'; 245 | alignChildren = 'fill'; 246 | 247 | add('statictext', undefined, 'Levels:'); 248 | var __levels = add('edittext', [0, 0, 40, 25], 0); 249 | __levels.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 0, 5); }); 250 | __levels.addEventListener('keyup', function (e) { previewStart(); }); 251 | add('statictext', undefined, 'Direction:'); 252 | var __container = add('dropdownlist', undefined, 'Horizontal,Vertical'.split(',')); 253 | __container.onChange = function () { previewStart(); } 254 | __container.selection = 0; 255 | } 256 | with (add('group')) { 257 | orientation = 'row'; 258 | alignChildren = 'fill'; 259 | 260 | var preview = add('checkbox', undefined, 'Preview'); 261 | } 262 | } 263 | 264 | with (win.add('group')) { 265 | orientation = 'row'; 266 | alignChildren = ['fill', 'fill']; 267 | 268 | var cancelBtn = add('button', undefined, 'Cancel'), 269 | copyButton = add('button', undefined, 'Apply Copy'), 270 | applyBtn = add('button', undefined, 'OK'); 271 | 272 | preview.onClick = function() { previewStart(); } 273 | cancelBtn.onClick = function() { win.close(); } 274 | copyButton.onClick = function() { 275 | if (preview.value && isUndo) { 276 | isUndo = false; 277 | $.forEach($items, function (item) { 278 | item.hidden = false; 279 | }); 280 | win.close(); 281 | } 282 | else { 283 | app.undo(); 284 | startAction(); 285 | isUndo = false; 286 | $.forEach($items, function (item) { 287 | item.hidden = false; 288 | }); 289 | win.close(); 290 | } 291 | } 292 | applyBtn.onClick = function() { 293 | if (preview.value && isUndo) { 294 | isUndo = false; 295 | $items.removeAll(); 296 | win.close(); 297 | } 298 | else { 299 | app.undo(); 300 | startAction(); 301 | isUndo = false; 302 | $items.removeAll(); 303 | win.close(); 304 | } 305 | } 306 | } 307 | 308 | function getData() { 309 | return { 310 | fragments: isNaN(Math.round(__fragments.text)) ? 10 : Math.round(__fragments.text), 311 | // rotate: isNaN(Math.round(__rotate.text)) ? 0 : Math.round(__rotate.text), 312 | offsetX: isNaN(Math.round(__offsetX.text)) ? 0 : Math.round(__offsetX.text), 313 | offsetY: isNaN(Math.round(__offsetY.text)) ? 0 : Math.round(__offsetY.text), 314 | levels: isNaN(Math.round(__levels.text)) ? 0 : Math.round(__levels.text), 315 | direction: (__container.selection.text.toLowerCase().slice(0,1) === 'h' ? 'x' : 'y') 316 | }; 317 | } 318 | 319 | function startAction() { 320 | rich_glitch($items, getData()); 321 | } 322 | 323 | function previewStart() { 324 | if (preview.value) { 325 | if (isUndo) app.undo(); 326 | else isUndo = true; 327 | 328 | app.redraw(); 329 | startAction(); 330 | app.redraw(); 331 | } 332 | else if (isUndo) { 333 | app.undo(); 334 | app.redraw(); 335 | isUndo = false; 336 | } 337 | } 338 | 339 | win.onClose = function () { 340 | if (isUndo) { 341 | app.undo(); 342 | app.redraw(); 343 | isUndo = false; 344 | } 345 | 346 | saveSettings(); 347 | return true; 348 | } 349 | 350 | function saveSettings() { 351 | try{ 352 | var $file = new File(settingFile.folder + settingFile.name), 353 | data = [ 354 | __fragments.text, 355 | // __rotate.text, 356 | __offsetX.text, 357 | __offsetY.text, 358 | __container.selection.index, 359 | __levels.text 360 | ].toString(); 361 | 362 | $file.open('w'); 363 | $file.write(data); 364 | $file.close(); 365 | }catch(e){$.errorMessage(e);} 366 | } 367 | 368 | function loadSettings() { 369 | var $file = File(settingFile.folder + settingFile.name); 370 | if ($file.exists) { 371 | try { 372 | $file.open('r'); 373 | var data = $file.read().split('\n'), 374 | $main = data[0].split(','); 375 | __fragments.text = __fragmentsSlider.value = parseInt($main[0]); 376 | // __rotate.text = __rotateSlider.value = parseInt($main[1]); 377 | __offsetX.text = __offsetXSlider.value = parseInt($main[1]); 378 | __offsetY.text = __offsetYSlider.value = parseInt($main[2]); 379 | __container.selection = parseInt($main[3]); 380 | __levels.text = parseInt($main[4]) || 0; 381 | } catch (e) {} 382 | $file.close(); 383 | } 384 | } 385 | 386 | function checkSettingFolder() { 387 | var $folder = new Folder(settingFile.folder); 388 | if (!$folder.exists) $folder.create(); 389 | } 390 | 391 | checkSettingFolder(); 392 | loadSettings(); 393 | 394 | selection = null; 395 | win.center(); 396 | win.show(); -------------------------------------------------------------------------------- /niceSlice.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ (presumably in Adobe Illustrator CS6 - did not test) 5 | Name: niceSlice.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | 12 | $.errorMessage = function (err) {alert(err + '\n' + err.line);}; 13 | Object.prototype.extend = function (userObject, deep) {try {for (var key in userObject) {if (this.hasOwnProperty(key)) {if (deep&& this[key] instanceof Object&& !(this[key] instanceof Array)&& userObject[key] instanceof Object&& !(userObject[key] instanceof Array)) {this[key].extend(userObject[key], deep);}else this[key] = userObject[key];}}return this;}catch (e) {$.errorMessage('$.objectParser() - error: ' + e);}}; 14 | $.toArr = function (classCollection, callback) {var arr = [], l = classCollection.length;if (l > 0) {for (var i = 0; i < l; i++) {arr.push(classCollection[i]);}}if (callback instanceof Function) return callback(arr);return arr;} 15 | Array.prototype.removeAll = function() { var i = this.length; if (i > 0) while (i--) this[i].remove(); return this; } 16 | 17 | var scriptName = 'NiceSlice', 18 | copyright = ' \u00A9 www.ladyginpro.ru', 19 | settingFile = { 20 | name: scriptName + '__setting.json', 21 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 22 | }, 23 | isUndo = false, 24 | $items = selection; 25 | 26 | function inputNumberEvents (ev, _input, min, max, callback){ 27 | var step, 28 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 29 | _value = parseFloat(_input.text), 30 | units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 31 | 32 | min = (min === undefined ? 0 : min); 33 | max = (max === undefined ? Infinity : max); 34 | step = (ev.shiftKey ? 10 : (ev.ctrlKey ? .1 : 1)); 35 | 36 | if (isNaN(_value)) { 37 | _input.text = min; 38 | } 39 | else { 40 | _value = ( ((_dir === 'u') || (_dir === 'r')) ? _value + step : (((_dir === 'd') || (_dir === 'l')) ? _value - step : false) ); 41 | if (_value !== false) { 42 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 43 | _input.text = _value; 44 | if (callback instanceof Function) callback(_value, _input, min, max, units); 45 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 46 | } 47 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 48 | } 49 | } 50 | 51 | function ungroup (group) { 52 | var i = group.pageItems.length; 53 | if (i > 0) while (i--) group.pageItems[i].moveBefore(group); 54 | group.remove(); 55 | } 56 | 57 | function getPosAnchors (anchors, xORy) { 58 | var arr = [], l = anchors.length; 59 | for (var i = 0; i < l; i++) { 60 | arr.push(anchors[i].anchor[xORy]); 61 | } 62 | return arr; 63 | } 64 | 65 | function rvbn (min, max) { 66 | // random value between numbers 67 | return min + Math.floor(Math.random() * (max - min)); 68 | } 69 | 70 | Array.prototype.randomArray = function() { 71 | var ix = this.length, ti, $i; 72 | while (0 !== ix) { 73 | $i = Math.floor(Math.random() * ix); 74 | ix -= 1; ti = this[ix]; 75 | this[ix] = this[$i]; 76 | this[$i] = ti; 77 | } 78 | return this; 79 | } 80 | 81 | function niceSlice (items, userOptions) { 82 | var options = { 83 | fragments: 10, 84 | width: 'random', 85 | /* 86 | auto 87 | random 88 | */ 89 | rotate: 0, 90 | offsetX: 10, // % of width 91 | offsetY: 10, // % of height 92 | gutter: 5, 93 | container: 'circle', 94 | /* 95 | square 96 | circle 97 | */ 98 | }.extend(userOptions || {}); 99 | 100 | options.fragments = (options.fragments > 0 ? options.fragments : 1) + 1; 101 | 102 | function randomWidth (maxsize) { 103 | var arr = []; 104 | for (var i = 0, j = options.fragments; i < options.fragments; i++, j--) { 105 | arr.push(rvbn(2, maxsize / 5)); 106 | maxsize -= arr[i]; 107 | } 108 | return arr; 109 | } 110 | 111 | function process (item) { 112 | var gutter = options.gutter, 113 | bnds = item.visibleBounds, 114 | $w = bnds[2] - bnds[0], 115 | $h = bnds[1] - bnds[3], 116 | isRW = (options.width === 'random'); 117 | 118 | if (options.container === 'circle') { 119 | var checkSizeRect = item.parent.pathItems.rectangle(bnds[1], bnds[0], $w, $h); 120 | checkSizeRect.rotate(options.rotate); 121 | $w = checkSizeRect.visibleBounds[2] - checkSizeRect.visibleBounds[0]; 122 | $h = checkSizeRect.visibleBounds[1] - checkSizeRect.visibleBounds[3]; 123 | checkSizeRect.remove(); 124 | } 125 | 126 | gutter = ($w / options.fragments) * (gutter / 100); 127 | 128 | var __w = ($w / options.fragments) - gutter + gutter / options.fragments, 129 | __h = $h, 130 | __t = bnds[1] + ($h - (bnds[1] - bnds[3])) / 2, 131 | __l = bnds[0] - ($w - (bnds[2] - bnds[0])) / 2, 132 | fragments = [], 133 | node, rect, group, 134 | evenOdd = 1; 135 | 136 | var gGroup = item.parent.groupItems.add(); 137 | gGroup.move(item, ElementPlacement.PLACEBEFORE); 138 | try { 139 | 140 | if (isRW) { 141 | var $rWidth = randomWidth(__w * options.fragments), 142 | $l = 0; 143 | } 144 | 145 | for (var i = 0; i < options.fragments; i++) { 146 | evenOdd = (i % 2 === 0 ? -1 : 1); 147 | if (isRW) { 148 | __w = $rWidth[i] + gutter; 149 | } 150 | else { 151 | __w = ((__w + gutter) * i); 152 | } 153 | group = gGroup.groupItems.add(); 154 | 155 | // create slice item 156 | rect = group.pathItems.rectangle(__t - (options.offsetY / 100 * $h * evenOdd), __l + $l + (options.offsetX / 100 * $w * evenOdd), __w, __h); 157 | if (isRW) $l += __w + gutter; 158 | 159 | // item 160 | node = item.duplicate(); 161 | node.top -= options.offsetY / 100 * $h * evenOdd; 162 | node.left += options.offsetX / 100 * $w * evenOdd; 163 | node.move(group, ElementPlacement.PLACEATEND); 164 | 165 | // clipping mask 166 | rect.clipping = group.clipped = true; 167 | 168 | fragments.push(group); 169 | } 170 | 171 | gGroup.rotate(options.rotate); 172 | ungroup(gGroup); 173 | 174 | for (var i = 0; i < options.fragments; i++) { 175 | fragments[i].pageItems[fragments[i].pageItems.length - 1].rotate(options.rotate * -1); 176 | } 177 | 178 | items[n].hidden = true; 179 | } 180 | catch(e){alert(e+'\n'+e.line);} 181 | 182 | return fragments; 183 | } 184 | 185 | var l = items.length; 186 | for (var n = 0; n < l; n++) { 187 | process(items[n]); 188 | } 189 | } 190 | 191 | 192 | var win = new Window('dialog', scriptName + copyright), 193 | sWidth = 120; 194 | 195 | with (win.add('panel')) { 196 | alignChildren = 'fill'; 197 | 198 | with (add('group')) { 199 | orientation = 'row'; 200 | alignChildren = 'fill'; 201 | 202 | add('statictext', undefined, 'Fragments:'); 203 | var __fragmentsSlider = add('slider', [0, 0, sWidth, 15], 10, 1, 20); 204 | __fragmentsSlider.maximumSize = [1000, 15]; 205 | __fragmentsSlider.onChanging = function (e) { __fragments.text = Math.round(this.value); } 206 | __fragmentsSlider.onChange = function (e) { previewStart(); } 207 | var __fragments = add('edittext', [0, 0, 50, 25], 10); 208 | __fragments.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 1, Infinity); __fragmentsSlider.value = Math.round(this.text); }); 209 | __fragments.addEventListener('keyup', function (e) { previewStart(); }); 210 | } 211 | with (add('group')) { 212 | orientation = 'row'; 213 | alignChildren = 'fill'; 214 | 215 | add('statictext', undefined, 'Rotate:'); 216 | var __rotateSlider = add('slider', [0, 0, sWidth + 24, 15], 0, 0, 360); 217 | __rotateSlider.maximumSize = [1000, 15]; 218 | __rotateSlider.onChanging = function (e) { __rotate.text = Math.round(this.value); } 219 | __rotateSlider.onChange = function (e) { previewStart(); } 220 | var __rotate = add('edittext', [0, 0, 50, 25], 0); 221 | __rotate.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 0, 360); __rotateSlider.value = Math.round(this.text); }); 222 | __rotate.addEventListener('keyup', function (e) { previewStart(); }); 223 | } 224 | with (add('group')) { 225 | orientation = 'row'; 226 | alignChildren = 'fill'; 227 | 228 | add('statictext', undefined, 'Offset X:'); 229 | var __offsetXSlider = add('slider', [0, 0, sWidth + 15, 15], 0, -100, 100); 230 | __offsetXSlider.maximumSize = [1000, 15]; 231 | __offsetXSlider.onChanging = function (e) { __offsetX.text = Math.round(this.value); } 232 | __offsetXSlider.onChange = function (e) { previewStart(); } 233 | var __offsetX = add('edittext', [0, 0, 50, 25], 0); 234 | __offsetX.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 100*-100, 100*100); __offsetXSlider.value = Math.round(this.text); }); 235 | __offsetX.addEventListener('keyup', function (e) { previewStart(); }); 236 | } 237 | with (add('group')) { 238 | orientation = 'row'; 239 | alignChildren = 'fill'; 240 | 241 | add('statictext', undefined, 'Offset Y:'); 242 | var __offsetYSlider = add('slider', [0, 0, sWidth + 15, 15], 0, -100, 100); 243 | __offsetYSlider.maximumSize = [1000, 15]; 244 | __offsetYSlider.onChanging = function (e) { __offsetY.text = Math.round(this.value); } 245 | __offsetYSlider.onChange = function (e) { previewStart(); } 246 | var __offsetY = add('edittext', [0, 0, 50, 25], 0); 247 | __offsetY.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 100*-100, 100*100); __offsetYSlider.value = Math.round(this.text); }); 248 | __offsetY.addEventListener('keyup', function (e) { previewStart(); }); 249 | } 250 | with (add('group')) { 251 | orientation = 'row'; 252 | alignChildren = 'fill'; 253 | 254 | add('statictext', undefined, 'Gutter:'); 255 | var __gutterSlider = add('slider', [0, 0, sWidth + 20, 15], 0, 0, 80); 256 | __gutterSlider.maximumSize = [1000, 15]; 257 | __gutterSlider.onChanging = function (e) { __gutter.text = Math.round(this.value); } 258 | __gutterSlider.onChange = function (e) { previewStart(); } 259 | var __gutter = add('edittext', [0, 0, 50, 25], 0); 260 | __gutter.addEventListener('keydown', function (e) { this.text = Math.round(this.text); inputNumberEvents(e, this, 0, 80); __gutterSlider.value = Math.round(this.text); }); 261 | __gutter.addEventListener('keyup', function (e) { previewStart(); }); 262 | } 263 | with (add('group')) { 264 | orientation = 'row'; 265 | alignChildren = 'fill'; 266 | 267 | add('statictext', undefined, 'Container:'); 268 | var __container = add('dropdownlist', undefined, 'Square,Circle'.split(',')); 269 | __container.onChange = function () { previewStart(); } 270 | __container.selection = 0; 271 | } 272 | } 273 | 274 | with (win.add('group')) { 275 | orientation = 'row'; 276 | alignChildren = ['fill', 'fill']; 277 | 278 | var preview = add('checkbox', undefined, 'Preview'), 279 | cancelBtn = add('button', undefined, 'Cancel'), 280 | applyBtn = add('button', undefined, 'OK'); 281 | 282 | preview.onClick = function() { previewStart(); } 283 | cancelBtn.onClick = function() { win.close(); } 284 | applyBtn.onClick = function() { 285 | if (preview.value && isUndo) { 286 | isUndo = false; 287 | $items.removeAll(); 288 | win.close(); 289 | } 290 | else { 291 | app.undo(); 292 | startAction(); 293 | isUndo = false; 294 | $items.removeAll(); 295 | win.close(); 296 | } 297 | } 298 | } 299 | 300 | function getData() { 301 | return { 302 | fragments: isNaN(Math.round(__fragments.text)) ? 10 : Math.round(__fragments.text), 303 | rotate: isNaN(Math.round(__rotate.text)) ? 0 : Math.round(__rotate.text), 304 | offsetX: isNaN(Math.round(__offsetX.text)) ? 0 : Math.round(__offsetX.text), 305 | offsetY: isNaN(Math.round(__offsetY.text)) ? 0 : Math.round(__offsetY.text), 306 | gutter: isNaN(Math.round(__gutter.text)) ? 5 : Math.round(__gutter.text), 307 | container: __container.selection.text.toLowerCase() 308 | }; 309 | } 310 | 311 | function startAction() { 312 | niceSlice($items, getData()); 313 | } 314 | 315 | function previewStart() { 316 | if (preview.value) { 317 | if (isUndo) app.undo(); 318 | else isUndo = true; 319 | 320 | app.redraw(); 321 | startAction(); 322 | app.redraw(); 323 | } 324 | else if (isUndo) { 325 | app.undo(); 326 | app.redraw(); 327 | isUndo = false; 328 | } 329 | } 330 | 331 | win.onClose = function () { 332 | if (isUndo) { 333 | app.undo(); 334 | app.redraw(); 335 | isUndo = false; 336 | } 337 | 338 | saveSettings(); 339 | return true; 340 | } 341 | 342 | function saveSettings() { 343 | try{ 344 | var $file = new File(settingFile.folder + settingFile.name), 345 | data = [ 346 | __fragments.text, 347 | __rotate.text, 348 | __offsetX.text, 349 | __offsetY.text, 350 | __gutter.text, 351 | __container.selection.index 352 | ].toString(); 353 | 354 | $file.open('w'); 355 | $file.write(data); 356 | $file.close(); 357 | }catch(e){$.errorMessage(e);} 358 | } 359 | 360 | function loadSettings() { 361 | var $file = File(settingFile.folder + settingFile.name); 362 | if ($file.exists) { 363 | try { 364 | $file.open('r'); 365 | var data = $file.read().split('\n'), 366 | $main = data[0].split(','); 367 | __fragments.text = __fragmentsSlider.value = parseInt($main[0]); 368 | __rotate.text = __rotateSlider.value = parseInt($main[1]); 369 | __offsetX.text = __offsetXSlider.value = parseInt($main[2]); 370 | __offsetY.text = __offsetYSlider.value = parseInt($main[3]); 371 | __gutter.text = __gutterSlider.value = parseInt($main[4]); 372 | __container.selection = parseInt($main[5]); 373 | } catch (e) {} 374 | $file.close(); 375 | } 376 | } 377 | 378 | function checkSettingFolder() { 379 | var $folder = new Folder(settingFile.folder); 380 | if (!$folder.exists) $folder.create(); 381 | } 382 | 383 | checkSettingFolder(); 384 | loadSettings(); 385 | 386 | selection = null; 387 | win.center(); 388 | win.show(); -------------------------------------------------------------------------------- /optimizero.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CS6+ 5 | Name: optimizero.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | var scriptName = 'Optimizero', 12 | copyright = ' \u00A9 www.ladyginpro.ru', 13 | settingFile = { 14 | name: scriptName + '__setting.json', 15 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 16 | }; 17 | 18 | $.errorMessage = function (err) {alert(err + '\n' + err.line);}; 19 | $.command = function (command) {try {app.executeMenuCommand(command);return $;}catch (e) {$.errorMessage('Command is " ' + command + ' " error: ' + e);}}; 20 | Object.prototype.extend = function (userObject, deep) {try {for (var key in userObject) {if (this.hasOwnProperty(key)) {if (deep&& this[key] instanceof Object&& !(this[key] instanceof Array)&& userObject[key] instanceof Object&& !(userObject[key] instanceof Array)) {this[key].extend(userObject[key], deep);}else this[key] = userObject[key];}}return this;}catch (e) {$.errorMessage('Object.extend() - error: ' + e);}}; 21 | Object.prototype.getAllParents = function () {function get(obj) {var arr = [];if (obj.parent.typename !== 'Application') {for (var i = 0; ; i++) {arr.push(obj.parent);if (obj.parent.parent.typename === 'Application') {return arr;}else {obj = obj.parent;}if (i === 1000) {break;}}}else {return obj;}}return get(this);}; 22 | Object.prototype.removeItemsWithArray = function (items) {var obj = [];for (var i = 0; i < this.length; i++) {if (!check(this[i])) {obj.push(this[i]);}}function check(e) {for (var j = 0; j < items.length; j++) {if (e === items[j]) {return true;}}return false;}return obj;}; 23 | Object.prototype.emptyLayers = function () {var arr = [];function check(layers) {var obj = [];for (var i = 0; i < layers.length; i++) {var subLayers = layers[i].subLayers(),emptySubLayers = layers[i].emptySubLayers(),count = subLayers.removeItemsWithArray(emptySubLayers).length;if (!count && !layers[i].pageItems.length) {obj = obj.concat(layers[i]);}}return obj;}var doc = this.typename === 'Document' ? [this] : this;for (var i = 0; i < doc.length; i++) {arr = arr.concat(check(doc[i].layers));}return arr;}; 24 | Object.prototype.subLayers = function (level) {var arr = [], count = 0;if (level !== undefined) {level = level - 1;}function __subLayers(layer) {var obj = [], sub = layer.layers;for (var j = 0; j < sub.length; j++) {obj = obj.concat(sub[j]);if ((level === undefined) || (sub[j].layers.length > 0 && count < level)) {obj = obj.concat(__subLayers(sub[j], count++));count--;}}return obj;}var obj = this.typename === 'Document' ? [this] : this;for (var j = 0; j < obj.length; j++) {arr = arr.concat(__subLayers(obj[j]));}return arr;}; 25 | Object.prototype.emptySubLayers = function (level) {var arr = [], obj = this.typename === 'Document' ? [this] : this;function process(sub) {var sub_arr = [];sub = sub.subLayers(level).reverse();for (var i = 0; i < sub.length; i++) {if (sub[i].pageItems.length > 0) {var parents = sub[i].pageItems[0].getAllParents();parents.pop();sub_arr = sub_arr.concat(parents);}}return sub.removeItemsWithArray(sub_arr).reverse();}for (var i = 0; i < obj.length; i++) {arr = arr.concat(process(obj[i]));}return arr;}; 26 | Array.prototype.__remove = function(){var i = this.length; if (i > 0) while (i--) this[i].remove();} 27 | 28 | function optimizero (userOptions) { 29 | var options = { 30 | hidden: false, 31 | ghost: false, 32 | rasterEmbed: false, 33 | symbolBreakLink: false, 34 | expandStyle: false, 35 | removeEmptyLayers: false, 36 | compoundFix: false, 37 | locked: 'skip', 38 | /* 39 | skip 40 | unlock 41 | remove 42 | */ 43 | guides: 'skip', 44 | /* 45 | skip 46 | newlayer 47 | remove 48 | */ 49 | openPaths: 'skip', 50 | /* 51 | skip 52 | join 53 | remove 54 | */ 55 | }.extend(userOptions || {}); 56 | 57 | options.guides = (typeof options.guides === 'string' ? options.guides.toLowerCase() : 'newlayer'); 58 | 59 | if (options.guides !== 'skip') { 60 | var layerGuides = activeDocument.layers.add(), 61 | guidesCollection = []; 62 | layerGuides.name = scriptName + '_guides'; 63 | } 64 | 65 | function compoundFixAction ($items) { 66 | function __ungroup (__items) { 67 | var l = __items.length; 68 | for (var i = 0; i < l; i++) { 69 | if (__items[i].typename === 'GroupItem') { 70 | var j = __items[i].pageItems.length; 71 | while (j--) { __items[i].pageItems[0].moveBefore(__items[i]); } 72 | __items[i].remove(); 73 | } 74 | } 75 | } 76 | 77 | function compoundFix (item) { 78 | selection = [item]; 79 | app.executeMenuCommand('noCompoundPath'); 80 | __ungroup(selection); 81 | app.executeMenuCommand('compoundPath'); 82 | selection = null; 83 | } 84 | 85 | function compoundPathItemsNormalize (items) { 86 | var i = items.length; 87 | while (i--) { 88 | if (items[i].typename === 'GroupItem') { 89 | compoundPathItemsNormalize(items[i].pageItems); 90 | } 91 | else if (items[i].typename === 'CompoundPathItem') { 92 | compoundFix(items[i]); 93 | } 94 | } 95 | } 96 | compoundPathItemsNormalize($items); 97 | } 98 | function layersOptimize (layers) { 99 | var n = layers.length; 100 | if (n > 0) while (n--) { 101 | if (options.hidden && !layers[n].visible) { 102 | layers[n].visible = true; 103 | layers[n].remove(); 104 | continue; 105 | } 106 | else if (options.locked !== 'skip' && layers[n].locked) { 107 | layers[n].locked = false; 108 | if (!(options.locked !== 'remove')) { 109 | layers[n].remove(); 110 | continue; 111 | } 112 | } 113 | layersOptimize(layers[n].layers); 114 | } 115 | } 116 | function itemsOptimize (items, $progress) { 117 | try { 118 | var i = items.length; 119 | if (!$progress) progressBarCounter = progressBar.maxvalue * 0.8 / i; 120 | 121 | while (i--) { 122 | if (options.guides !== 'skip' && items[i].guides) { 123 | guidesCollection.push(items[i]); 124 | } 125 | else if (options.hidden && items[i].hidden) { 126 | items[i].hidden = true; 127 | items[i].remove(); 128 | } 129 | else if (options.locked !== 'skip' && items[i].locked) { 130 | if (options.locked !== 'remove') items[i].locked = false; 131 | else items[i].remove(); 132 | } 133 | else if (options.ghost && items[i].typename.indexOf('PathItem') > -1) { 134 | try { 135 | var __items = (items[i].typename === 'CompoundPathItem' ? items[i].pathItems[0] : items[i]); 136 | if (!__items.stroked && !__items.filled && !__items.guides && 137 | !(__items.clipping && __items.parent.clipped) 138 | ) { 139 | items[i].remove(); 140 | } 141 | else if (!items[i].closed && items[i].pathPoints && items[i].pathPoints.length > 2) { 142 | switch (options.openPaths.toLowerCase().replace(/ /g, '')) { 143 | case 'join' : items[i].closed = true; break; 144 | case 'remove' : items[i].remove(); break; 145 | } 146 | } 147 | }catch (e) {} 148 | } 149 | else if (items[i].typename === 'GroupItems') { 150 | itemsOptimize(items[i].pageItems, true); 151 | } 152 | 153 | if (!$progress) { progressBar.value += progressBarCounter; win.update(); } 154 | } 155 | } 156 | catch(err) { 157 | $.errorMessage(err); 158 | } 159 | } 160 | 161 | function optimizeRasters() { 162 | if (options.rasterEmbed) { 163 | var i = activeDocument.placedItems.length; 164 | if (i > 0) while (i--) { 165 | activeDocument.placedItems[i].embed(); 166 | } 167 | } 168 | } 169 | function optimizeSymbols() { 170 | if (options.symbolBreakLink) { 171 | var i = activeDocument.symbolItems.length; 172 | if (i > 0) while (i--) { 173 | activeDocument.symbolItems[i].breakLink(); 174 | } 175 | } 176 | } 177 | 178 | 179 | selection = null; 180 | if (options.expandStyle) $.command('selectall').command('expandStyle'); 181 | if (options.compoundFix) compoundFixAction(activeDocument.compoundPathItems); 182 | selection = null; 183 | if (options.locked !== 'skip' || options.hidden) { 184 | layersOptimize(activeDocument.layers); 185 | } 186 | if (options.guides !== 'skip' || options.locked !== 'skip' || options.ghost || options.hidden) { 187 | itemsOptimize(activeDocument.pageItems); 188 | } 189 | optimizeRasters(); 190 | optimizeSymbols(); 191 | if (options.guides !== 'skip') { 192 | var i = guidesCollection.length; 193 | if (i > 0) while (i--) { options.guides !== 'remove' ? guidesCollection[i].moveToBeginning(layerGuides) : guidesCollection[i].remove(); } 194 | } 195 | if (options.emptyLayers) { 196 | activeDocument.emptyLayers().__remove(); 197 | progressBar.value += progressBar.maxvalue * 0.2; 198 | win.update(); 199 | } 200 | selection = null; 201 | } 202 | 203 | 204 | var win = new Window('dialog', scriptName + copyright); 205 | win.alignChildren = 'fill'; 206 | 207 | 208 | with (globalGroup = win.add('group')) { 209 | orientation = 'column'; 210 | alignChildren = 'fill'; 211 | 212 | with (panel = add('panel')) { 213 | alignChildren = 'fill'; 214 | 215 | var checkHidden = add('checkbox', undefined, 'Remove Hidden items'); 216 | checkHidden.value = true; 217 | var checkGhost = add('checkbox', undefined, 'Remove Ghost items'); 218 | checkGhost.value = true; 219 | var checkCompoundFix = add('checkbox', undefined, 'Fix Compound Path Items'); 220 | checkCompoundFix.value = true; 221 | var checkRemoveEmptyLayers = add('checkbox', undefined, 'Remove empty layers'); 222 | checkRemoveEmptyLayers.value = true; 223 | var checkRasterEmbed = add('checkbox', undefined, 'Embed rester items'); 224 | checkRasterEmbed.value = true; 225 | var checkSymbolBreakLink = add('checkbox', undefined, 'Symbols break link'); 226 | checkSymbolBreakLink.value = true; 227 | var checkExpandStyle = add('checkbox', undefined, 'Expand items (styles)'); 228 | checkExpandStyle.helpTip = 'Expand brushes, symbols, effects ...'; 229 | checkExpandStyle.value = true; 230 | var dlistLocked = add('dropdownlist', undefined, 'Locked items: Skip,Locked items: Unlock,Locked items: Remove'.split(',')); 231 | dlistLocked.selection = 0; 232 | var dlistOpenPaths = add('dropdownlist', undefined, 'Open paths: Join,Open paths: Remove,Open paths: Skip'.split(',')); 233 | dlistOpenPaths.selection = 0; 234 | var dlistGuides = add('dropdownlist', undefined, 'Guides: Skip,Guides: Remove,Guides: Move to new layer'.split(',')); 235 | dlistGuides.selection = 1; 236 | } 237 | 238 | with (add('group')) { 239 | orientation = 'row'; 240 | alignChildren = ['fill', 'fill']; 241 | 242 | var cancel = add('button', undefined, 'Cancel'); 243 | cancel.helpTip = 'Press Esc to Close'; 244 | cancel.onClick = function () { win.close(); } 245 | 246 | var ok = add('button', [0, 0, 100, 30], 'Optimize'); 247 | ok.helpTip = 'Press Enter to Run'; 248 | ok.onClick = startAction; 249 | ok.active = true; 250 | } 251 | } 252 | 253 | var progressBar = win.add('progressbar'), 254 | progressBarCounter = 100; 255 | progressBar.value = 0; 256 | progressBar.minvalue = 0; 257 | progressBar.maxvalue = progressBarCounter; 258 | progressBar.maximumSize = [1000, 5]; 259 | 260 | 261 | 262 | function startAction() { 263 | try { 264 | globalGroup.enabled = false; 265 | 266 | optimizero({ 267 | hidden: checkHidden.value, 268 | locked: dlistLocked.selection.text.toLowerCase().replace(/ /g, '').replace('lockeditems:', ''), 269 | ghost: checkGhost.value, 270 | compoundFix: checkCompoundFix.value, 271 | rasterEmbed: checkRasterEmbed.value, 272 | symbolBreakLink: checkSymbolBreakLink.value, 273 | expandStyle: checkExpandStyle.value, 274 | guides: dlistGuides.selection.text.toLowerCase().replace(/ /g, '').replace('guides:', ''), 275 | removeEmptyLayers: checkRemoveEmptyLayers.value, 276 | openPaths: dlistOpenPaths.selection.text.toLowerCase().replace(/ /g, '').replace('openpaths:', ''), 277 | }); 278 | } 279 | catch(err) 280 | {$.errorMessage(err); 281 | } 282 | 283 | win.close(); 284 | } 285 | 286 | 287 | function saveSettings() { 288 | var $file = new File(settingFile.folder + settingFile.name), 289 | data = [ 290 | checkHidden.value, 291 | dlistLocked.selection.index, 292 | checkGhost.value, 293 | dlistGuides.selection.index, 294 | checkRemoveEmptyLayers.value, 295 | checkRasterEmbed.value, 296 | checkExpandStyle.value, 297 | dlistOpenPaths.selection.index, 298 | checkCompoundFix.value, 299 | checkSymbolBreakLink.value 300 | ].toString(); 301 | 302 | $file.open('w'); 303 | $file.write(data); 304 | $file.close(); 305 | } 306 | 307 | function loadSettings() { 308 | var $file = File(settingFile.folder + settingFile.name); 309 | if ($file.exists) { 310 | try { 311 | $file.open('r'); 312 | var data = $file.read().split('\n'), 313 | $main = data[0].split(','); 314 | checkHidden.value = ($main[0] === 'true'); 315 | dlistLocked.selection = parseInt($main[1]); 316 | checkGhost.value = ($main[2] === 'true'); 317 | dlistGuides.selection = parseInt($main[3]); 318 | checkRemoveEmptyLayers.value = ($main[4] === 'true'); 319 | checkRasterEmbed.value = ($main[5] === 'true'); 320 | checkExpandStyle.value = ($main[6] === 'true'); 321 | dlistOpenPaths.selection = parseInt($main[7]); 322 | checkCompoundFix.value = ($main[8] === 'true'); 323 | checkSymbolBreakLink.value = ($main[9] === 'true'); 324 | } catch (e) {} 325 | $file.close(); 326 | } 327 | } 328 | 329 | win.onClose = function() { 330 | saveSettings(); 331 | return true; 332 | } 333 | 334 | function checkSettingFolder() { 335 | var $folder = new Folder(settingFile.folder); 336 | if (!$folder.exists) $folder.create(); 337 | } 338 | 339 | checkSettingFolder(); 340 | loadSettings(); 341 | win.center(); 342 | win.show(); -------------------------------------------------------------------------------- /circular.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Alexander Ladygin (i@ladygin.pro) 4 | Program version: Adobe Illustrator CC+ (presumably in Adobe Illustrator CS6 - did not test) 5 | Name: circular.jsx; 6 | 7 | Copyright (c) 2018 8 | www.ladyginpro.ru 9 | 10 | */ 11 | 12 | $.errorMessage = function (err) {alert(err + '\n' + err.line);}; 13 | Object.prototype.extend = function (userObject, deep) {try {for (var key in userObject) {if (this.hasOwnProperty(key)) {if (deep&& this[key] instanceof Object&& !(this[key] instanceof Array)&& userObject[key] instanceof Object&& !(userObject[key] instanceof Array)) {this[key].extend(userObject[key], deep);}else this[key] = userObject[key];}}return this;}catch (e) {$.errorMessage('$.objectParser() - error: ' + e);}}; 14 | $.getBounds = function (arr, bounds) {bounds = bounds || 'geometricBounds';bounds = (bounds && bounds.toLowerCase().indexOf('bounds') === -1) ? bounds += 'Bounds' : bounds;var x = [], y = [], w = [], h = [];for (var i = 0; i < arr.length; i++) {x.push(arr[i][bounds][0]);y.push(arr[i][bounds][1]);w.push(arr[i][bounds][2]);h.push(arr[i][bounds][3]);};return [Math.min.apply(null, x), Math.max.apply(null, y), Math.max.apply(null, w), Math.min.apply(null, h)];}; 15 | $.toArr = function (classCollection, callback) {var arr = [], l = classCollection.length;if (l > 0) {for (var i = 0; i < l; i++) {arr.push(classCollection[i]);}}if (callback instanceof Function) return callback(arr);return arr;} 16 | $.getUnits = function (val, def) {return 'px,pt,mm,cm,in,pc'.indexOf(val.slice(-2)) > -1 ? val.slice(-2) : def;}; 17 | $.convertUnits = function (obj, b) {if (obj === undefined) {return obj;}if (b === undefined) {b = 'px';}if (typeof obj === 'number') {obj = obj + 'px';}if (typeof obj === 'string') {var unit = $.getUnits(obj),val = parseFloat(obj);if (unit && !isNaN(val)) {obj = val;}else if (!isNaN(val)) {obj = val; unit = 'px';}}if (((unit === 'px') || (unit === 'pt')) && (b === 'mm')) {obj = parseFloat(obj) / 2.83464566929134;}else if (((unit === 'px') || (unit === 'pt')) && (b === 'cm')) {obj = parseFloat(obj) / (2.83464566929134 * 10);}else if (((unit === 'px') || (unit === 'pt')) && (b === 'in')) {obj = parseFloat(obj) / 72;}else if ((unit === 'mm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134;}else if ((unit === 'mm') && (b === 'cm')) {obj = parseFloat(obj) * 10;}else if ((unit === 'mm') && (b === 'in')) {obj = parseFloat(obj) / 25.4;}else if ((unit === 'cm') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 2.83464566929134 * 10;}else if ((unit === 'cm') && (b === 'mm')) {obj = parseFloat(obj) / 10;}else if ((unit === 'cm') && (b === 'in')) {obj = parseFloat(obj) * 2.54;}else if ((unit === 'in') && ((b === 'px') || (b === 'pt'))) {obj = parseFloat(obj) * 72;}else if ((unit === 'in') && (b === 'mm')) {obj = parseFloat(obj) * 25.4;}else if ((unit === 'in') && (b === 'cm')) {obj = parseFloat(obj) * 25.4;}return parseFloat(obj);}; 18 | 19 | var isUndo = false, 20 | scriptName = 'Circular', 21 | copyright = ' \u00A9 www.ladyginpro.ru', 22 | settingFile = { 23 | name: scriptName + '__setting.json', 24 | folder: Folder.myDocuments + '/LA_AI_Scripts/' 25 | }, 26 | $items = selection; 27 | 28 | function ungroup (group) { 29 | var i = group.pageItems.length; 30 | if (i > 0) while (i--) group.pageItems[i].moveBefore(group); 31 | group.remove(); 32 | } 33 | 34 | function rvbn (min, max) { 35 | // random value between numbers 36 | return min + Math.floor(Math.random() * (max - min)); 37 | } 38 | 39 | function circular (userOptions) { 40 | var options = { 41 | copies: 7, 42 | offset: 200, 43 | offsetRandom: false, 44 | offsetMin: '0 px', 45 | offsetMax: '0 px', 46 | angleStart: 0, 47 | angleEnd: 360, 48 | notCopies: true, 49 | resetItem: true, 50 | bounds: 'visible', 51 | direction: 'down', 52 | isRotateItem: false, 53 | rotateItemAngle: 45, 54 | position: 'relative', 55 | counterclockwise: false, 56 | }.extend(userOptions || {}); 57 | 58 | var CCW = !options.counterclockwise ? -1 : 1, 59 | TFP = options.direction.toUpperCase().replace('UP', 'TOP').replace('DOWN', 'BOTTOM'); 60 | options.bounds = (options.bounds.slice(0,1).toLowerCase() === 'v' ? 'visibleBounds' : 'geometricBounds'); 61 | options.direction = options.direction.toLowerCase().slice(0,1); 62 | options.copies = (options.copies > 0 ? options.copies : 1); 63 | options.offset = $.convertUnits(options.offset, 'px'); 64 | options.offsetMin = $.convertUnits(options.offsetMin, 'px'); 65 | options.offsetMax = $.convertUnits(options.offsetMax, 'px'); 66 | 67 | var sbnds = $.getBounds($items, options.bounds), 68 | cpos = { 69 | x: sbnds[0] + (sbnds[2] - sbnds[0]) / 2, 70 | y: sbnds[1] - (sbnds[1] - sbnds[3]) / 2, 71 | }; 72 | 73 | if (options.notCopies) { 74 | var items = $items, l = items.length, 75 | aVal = (options.angleEnd - options.angleStart) / (l > 1 ? (options.angleEnd >= 350 ? l : l - 1) : l); 76 | // aVal = (options.angleEnd - options.angleStart) / (l - 1 > 0 ? l - 1 : l); 77 | 78 | for (var i = 0; i < l; i++) { 79 | toRotate(items[i], options.angleStart + aVal * i, cpos); 80 | } 81 | } 82 | else { 83 | var items = $items, l = items.length, 84 | aVal = (options.angleEnd - options.angleStart) / options.copies; 85 | for (var i = 0; i < l; i++) { 86 | for (var j = 0; j < options.copies; j++) { 87 | toRotate(items[i], options.angleStart + aVal * j); 88 | } 89 | // items[i].remove(); 90 | } 91 | } 92 | 93 | function toRotate (item, angle, $pos) { 94 | angle *= CCW; 95 | 96 | var $offset = (options.offsetRandom ? rvbn(options.offsetMin, options.offsetMax) : options.offset), 97 | bnds = item[options.bounds], 98 | $w = bnds[2] - bnds[0], 99 | $h = bnds[1] - bnds[3]; 100 | 101 | if (options.position.toLowerCase().slice(0,1) === 'r') $offset += ($w >= $h ? $w : $h); 102 | 103 | // align center 104 | if (options.notCopies) { 105 | item.position = [$pos.x - $w / 2, $pos.y + $h / 2]; 106 | bnds = item[options.bounds]; 107 | } 108 | 109 | var centerPointSize = 0, 110 | $group = item.parent.groupItems.add(), 111 | node = (options.notCopies ? item : item.duplicate($group, ElementPlacement.INSIDE)), 112 | centerPoint = $group.pathItems.ellipse(bnds[1] - $h / 2 + centerPointSize / 2, bnds[0] + $w / 2 - centerPointSize / 2, centerPointSize, centerPointSize); 113 | 114 | // move items 115 | $group.moveBefore(item); 116 | if (options.notCopies) node.moveToBeginning($group); 117 | 118 | // set $offset 119 | // node.position = [node.position[0], node.position[1] - $offset]; 120 | if (options.direction === 'u') node.top -= $offset; 121 | else if (options.direction === 'r') node.left -= $offset; 122 | else if (options.direction === 'd') node.top += $offset; 123 | else if (options.direction === 'l') node.left += $offset; 124 | 125 | // rotate item 126 | $group.rotate(angle, true, true, true, true, Transformation[TFP]); 127 | 128 | // reset rotate from the item 129 | if (options.resetItem) node.rotate(angle * -1, true, true, true, true, Transformation.CENTER); 130 | // rotate only item 131 | if (options.isRotateItem) node.rotate((__randomRotate.value ? Math.floor(Math.random() * 360) : options.rotateItemAngle * CCW), true, true, true, true, Transformation.CENTER); 132 | 133 | centerPoint.remove(); 134 | ungroup($group); 135 | 136 | return item; 137 | } 138 | 139 | } 140 | 141 | function inputNumberEvents (ev, _input, min, max, callback){ 142 | var step, 143 | _dir = (ev.keyName ? ev.keyName.toLowerCase().slice(0,1) : '#none#'), 144 | _value = parseFloat(_input.text), 145 | units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : ''); 146 | 147 | min = (min === undefined ? 0 : min); 148 | max = (max === undefined ? Infinity : max); 149 | step = (ev.shiftKey ? 10 : (ev.ctrlKey ? .1 : 1)); 150 | 151 | if (isNaN(_value)) { 152 | _input.text = min; 153 | } 154 | else { 155 | _value = ( ((_dir === 'u') || (_dir === 'r')) ? _value + step : (((_dir === 'd') || (_dir === 'l')) ? _value - step : false) ); 156 | if (_value !== false) { 157 | _value = (_value <= min ? min : (_value >= max ? max : _value)) 158 | _input.text = _value; 159 | if (callback instanceof Function) callback(_value, _input, min, max, units); 160 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 161 | } 162 | else if (units) _input.text = parseFloat(_input.text) + ' ' + units; 163 | } 164 | } 165 | 166 | function normalizeAngle (val, item, min, max) { 167 | if (item === __startAngle) { 168 | if (val > parseFloat(__endAngle.text)) { __endAngleSlider.value = __endAngle.text = ((val + 1) >= max ? max : val + 1); } 169 | } 170 | else if (item === __endAngle) { 171 | if (val < parseFloat(__startAngle.text)) { __startAngleSlider.value = __startAngle.text = ((val - 1) <= min ? min - 1 : val - 1); } 172 | } 173 | } 174 | 175 | function normalizeOffset (val, item, min, max, units) { 176 | if (item === __offsetMin) { 177 | if (val > $.convertUnits(__offsetMax.text, 'px')) { 178 | __offsetMax.text = ((val + 1) >= max ? max : val + 1) + (units ? ' ' + units : ''); 179 | } 180 | } 181 | else if (item === __offsetMax) { 182 | if (val < $.convertUnits(__offsetMin.text, 'px')) { 183 | __offsetMin.text = ((val - 1) <= min ? min - 1 : val - 1) + (units ? ' ' + units : ''); 184 | } 185 | } 186 | 187 | if (units) item.text += ' ' + units; 188 | } 189 | 190 | var win = new Window('dialog', scriptName + copyright); 191 | win.alignChildren = 'fill'; 192 | 193 | with (panel = win.add('panel')) { 194 | alignChildren = ['fill', 'bottom']; 195 | 196 | with (add('group')) { 197 | orientation = 'row'; 198 | 199 | add('statictext', [0, 0, 80, 25], 'Start angle:').justify = 'center'; 200 | var __startAngleSlider = add('slider', [0, 0, 170, 15], 0, 0, 359), 201 | __startAngle = add('edittext', [0, 0, 50, 25], 0); 202 | __startAngleSlider.onChanging = function (e) { __startAngle.text = Math.round(this.value); normalizeAngle(Math.round(this.value), __startAngle, 1, 360); } 203 | __startAngleSlider.onChange = function (e) { previewStart(); } 204 | __startAngle.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 0, 359); __startAngleSlider.value = Math.round(this.text); }); 205 | __startAngle.addEventListener('keyup', function (e) { normalizeAngle(this.value, __startAngle, 1, 360); previewStart(); }); 206 | } 207 | with (add('group')) { 208 | orientation = 'row'; 209 | 210 | var __isEndAngle = add('checkbox', [0, 0, 80, 25], 'End angle:'), 211 | __endAngleSlider = add('slider', [0, 0, 170, 15], 360, 1, 360), 212 | __endAngle = add('edittext', [0, 0, 50, 25], 360); 213 | __isEndAngle.alignment = 'bottom'; 214 | __endAngleSlider.onChanging = function (e) { __endAngle.text = Math.round(this.value); normalizeAngle(Math.round(this.value), __endAngle, 1, 360); } 215 | __endAngleSlider.onChange = function (e) { previewStart(); } 216 | __endAngle.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 1, 360); __endAngleSlider.value = Math.round(this.text); }); 217 | __endAngle.addEventListener('keyup', function (e) { normalizeAngle(this.value, __endAngle, 1, 360); previewStart(); }); 218 | 219 | __isEndAngle.onClick = function () { __endAngleSlider.enabled = __endAngle.enabled = this.value; previewStart(); } 220 | __endAngleSlider.enabled = __endAngle.enabled = false; 221 | } 222 | with (add('group')) { 223 | orientation = 'row'; 224 | 225 | var __isRotateItem = add('checkbox', undefined, 'Rotate each items'), 226 | __randomRotate = add('checkbox', undefined, 'Rotate each items Random'); 227 | 228 | __isRotateItem.onClick = function () { 229 | __randomRotate.enabled = this.value; 230 | __rotateItemSlider.enabled = __rotateItemAngle.enabled = (this.value && __randomRotate.value ? false : this.value); 231 | previewStart(); 232 | } 233 | __randomRotate.onClick = function () { __rotateItemSlider.enabled = __rotateItemAngle.enabled = !this.value; previewStart(); } 234 | } 235 | with (add('group')) { 236 | var __rotateItemSlider = add('slider', [0, 0, 260, 15], 360, 0, 360), 237 | __rotateItemAngle = add('edittext', [0, 0, 50, 25], 360); 238 | 239 | __rotateItemSlider.onChanging = function (e) { __rotateItemAngle.text = Math.round(this.value); normalizeAngle(Math.round(this.value), __rotateItemAngle, 0, 360); } 240 | __rotateItemSlider.onChange = function (e) { previewStart(); } 241 | __rotateItemAngle.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 0, 360); __rotateItemSlider.value = Math.round(this.text); }); 242 | __rotateItemAngle.addEventListener('keyup', function (e) { previewStart(); }); 243 | __rotateItemSlider.enabled = __rotateItemAngle.enabled = false; 244 | } 245 | with (add('group')) { 246 | orientation = 'row'; 247 | alignChildren = ['fill', 'fill']; 248 | 249 | add('statictext', undefined, 'Offset:'); 250 | var __offset = add('edittext', [0, 0, 100, 25], '0 px'), 251 | __direction = add('dropdownlist', undefined, 'Direction: Up,Direction: Right,Direction: Down,Direction: Left'.split(',')); 252 | __direction.selection = 0; 253 | __offset.addEventListener('keydown', function (e) { inputNumberEvents(e, this, -Infinity, Infinity); }); 254 | __offset.addEventListener('keyup', function (e) { previewStart(); }); 255 | __direction.onChange = function () { previewStart(); } 256 | } 257 | with (add('group')) { 258 | orientation = 'row'; 259 | alignChildren = ['fill', 'fill']; 260 | 261 | // add('statictext', undefined, 'Offset:'); 262 | var __randomOffset = add('checkbox', undefined, 'Random offset'); 263 | __randomOffset.alignment = 'bottom'; 264 | add('statictext', undefined, 'Min:'); 265 | var __offsetMin = add('edittext', [0, 0, 60, 25], '0 px'); 266 | add('statictext', undefined, 'Max:'); 267 | var __offsetMax = add('edittext', [0, 0, 60, 25], '0 px'); 268 | 269 | __offsetMin.enabled = __offsetMax.enabled = __randomOffset.value; 270 | 271 | __randomOffset.onClick = function () { 272 | __offsetMin.enabled = __offsetMax.enabled = this.value; 273 | __offset.enabled = !this.value; 274 | previewStart(); 275 | } 276 | __offsetMin.addEventListener('keydown', function (e) { inputNumberEvents(e, __offsetMin, 0, Infinity, normalizeOffset); }); 277 | __offsetMin.addEventListener('change', function (e) { normalizeOffset($.convertUnits(this.text, 'px'), __offsetMin, 0, Infinity); }); 278 | __offsetMin.addEventListener('keyup', function (e) { previewStart(); }); 279 | __offsetMax.addEventListener('keydown', function (e) { inputNumberEvents(e, __offsetMax, 0, Infinity, normalizeOffset); }); 280 | __offsetMax.addEventListener('change', function (e) { normalizeOffset($.convertUnits(this.text, 'px'), __offsetMax, 0, Infinity); }); 281 | __offsetMax.addEventListener('keyup', function (e) { previewStart(); }); 282 | } 283 | 284 | __offset.enabled = !__randomOffset.value; 285 | 286 | with (add('group')) { 287 | orientation = 'row'; 288 | alignChildren = ['fill', 'fill']; 289 | 290 | var __pos = add('dropdownlist', [0, 0, 105, 25], 'Position: Absolute,Position: Relative'.split(',')); 291 | __pos.selection = 1; 292 | __pos.onChange = function () { previewStart(); } 293 | var __bounds = add('dropdownlist', [0, 0, 105, 25], 'Bounds: Geometric,Bounds: Visible'.split(',')); 294 | __bounds.selection = 0; 295 | __bounds.onChange = function () { previewStart(); } 296 | } 297 | with (add('group')) { 298 | orientation = 'row'; 299 | alignChildren = 'left'; 300 | 301 | var __counterClockwise = add('checkbox', undefined, 'Counter Clockwise'); 302 | __counterClockwise.onClick = function () { previewStart(); } 303 | var __notRotate = add('checkbox', undefined, 'Reset rotate from item'); 304 | __notRotate.onClick = function () { previewStart(); } 305 | } 306 | with (add('group')) { 307 | orientation = 'row'; 308 | alignChildren = 'left'; 309 | 310 | var __copiesEnabled = add('checkbox', undefined, 'Copies enabled'); 311 | __copiesEnabled.onClick = function () { __copies.enabled = this.value; previewStart(); } 312 | var __copies = add('edittext', [0, 0, 200, 25], 1); 313 | __copies.enabled = false; 314 | __copies.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 1, Infinity); this.text = parseInt(this.text); }); 315 | __copies.addEventListener('keyup', function (e) { previewStart(); }); 316 | __copies.onChange = function () { if (isNaN(parseInt(this.text))) this.text = 1; } 317 | } 318 | } 319 | 320 | with (win.add('group')) { 321 | orientation = 'row'; 322 | alignChildren = ['fill', 'fill']; 323 | 324 | var preview = add('checkbox', undefined, 'Preview'), 325 | cancelBtn = add('button', undefined, 'Cancel'), 326 | applyBtn = add('button', undefined, 'OK'); 327 | 328 | preview.onClick = function() { previewStart(); } 329 | cancelBtn.onClick = function() { win.close(); } 330 | applyBtn.onClick = function() { 331 | if (preview.value && isUndo) { 332 | isUndo = false; 333 | win.close(); 334 | } 335 | else { 336 | app.undo(); 337 | startAction(); 338 | isUndo = false; 339 | win.close(); 340 | } 341 | } 342 | } 343 | 344 | function getData() { 345 | return { 346 | copies: parseInt(__copies.text), 347 | offset: __offset.text, 348 | angleStart: parseInt(__startAngle.text), 349 | angleEnd: (!__isEndAngle.value ? 360 : parseInt(__endAngle.text)), 350 | notCopies: !__copiesEnabled.value, 351 | resetItem: __notRotate.value, 352 | bounds: __bounds.selection.text.toLowerCase().replace('bounds: ', ''), 353 | direction: __direction.selection.text.toLowerCase().replace('direction: ', ''), 354 | position: __pos.selection.text.toLowerCase().replace('position: ', ''), 355 | counterclockwise: __counterClockwise.value, 356 | isRotateItem: __isRotateItem.value, 357 | rotateItemAngle: __rotateItemSlider.value, 358 | offsetRandom: __randomOffset.value, 359 | offsetMin: __offsetMin.text, 360 | offsetMax: __offsetMax.text, 361 | }; 362 | } 363 | 364 | 365 | function startAction() { 366 | circular(getData()); 367 | } 368 | 369 | function previewStart() { 370 | if (preview.value) { 371 | if (isUndo) app.undo(); 372 | else isUndo = true; 373 | 374 | startAction(); 375 | app.redraw(); 376 | } 377 | else if (isUndo) { 378 | app.undo(); 379 | app.redraw(); 380 | isUndo = false; 381 | } 382 | } 383 | 384 | win.onClose = function () { 385 | if (isUndo) { 386 | app.undo(); 387 | app.redraw(); 388 | isUndo = false; 389 | } 390 | 391 | // selection = $items; 392 | saveSettings(); 393 | return true; 394 | } 395 | 396 | function saveSettings() { 397 | try{ 398 | var $file = new File(settingFile.folder + settingFile.name), 399 | data = [ 400 | __startAngleSlider.value, 401 | __startAngle.text, 402 | __isEndAngle.value, 403 | __endAngleSlider.value, 404 | __endAngle.text, 405 | __offset.text, 406 | __direction.selection.index, 407 | __pos.selection.index, 408 | __bounds.selection.index, 409 | __counterClockwise.value, 410 | __notRotate.value, 411 | __copiesEnabled.value, 412 | __copies.text, 413 | __isRotateItem.value, 414 | __rotateItemSlider.value, 415 | __rotateItemAngle.text, 416 | __randomRotate.value, 417 | __randomOffset.value, 418 | __offsetMin.text, 419 | __offsetMax.text 420 | ].toString(); 421 | 422 | $file.open('w'); 423 | $file.write(data); 424 | $file.close(); 425 | }catch(e){$.errorMessage(e);} 426 | } 427 | 428 | function loadSettings() { 429 | var $file = File(settingFile.folder + settingFile.name); 430 | if ($file.exists) { 431 | try { 432 | $file.open('r'); 433 | var data = $file.read().split('\n'), 434 | $main = data[0].split(','); 435 | __startAngleSlider.value = parseInt($main[0]); 436 | __startAngle.text = $main[1]; 437 | __isEndAngle.value = ($main[2] === 'true'); 438 | __endAngleSlider.value = parseInt($main[3]); 439 | __endAngle.text = $main[4]; 440 | __offset.text = $main[5]; 441 | __direction.selection.index = parseInt($main[6]); 442 | __pos.selection.index = parseInt($main[7]); 443 | __bounds.selection.index = parseInt($main[8]) 444 | __counterClockwise.value = ($main[9] === 'true'); 445 | __notRotate.value = ($main[10] === 'true'); 446 | __copiesEnabled.value = ($main[11] === 'true'); 447 | __copies.text = $main[12]; 448 | __isRotateItem.value = ($main[13] === 'true'); 449 | __rotateItemSlider.value = parseInt($main[14]); 450 | __rotateItemAngle.text = $main[15]; 451 | __randomRotate.value = ($main[16] === 'true'); 452 | if ($main[17]) __randomOffset.value = ($main[17] === 'true'); 453 | if ($main[18]) __offsetMin.text = $main[18]; 454 | if ($main[19]) __offsetMax.text = $main[19]; 455 | 456 | __copies.enabled = __copiesEnabled.value; 457 | __endAngleSlider.enabled = __endAngle.enabled = __isEndAngle.value; 458 | __randomRotate.enabled = __isRotateItem.value; 459 | __rotateItemSlider.enabled = __rotateItemAngle.enabled = (__isRotateItem.value && __randomRotate.value ? false : __isRotateItem.value); 460 | 461 | __offset.enabled = !__randomOffset.value; 462 | __offsetMin.enabled = __offsetMax.enabled = __randomOffset.value; 463 | } catch (e) {} 464 | $file.close(); 465 | } 466 | } 467 | 468 | function checkSettingFolder() { 469 | var $folder = new Folder(settingFile.folder); 470 | if (!$folder.exists) $folder.create(); 471 | } 472 | 473 | checkSettingFolder(); 474 | loadSettings(); 475 | 476 | selection = null; 477 | app.redraw(); 478 | 479 | win.center(); 480 | win.show(); --------------------------------------------------------------------------------