Skip to content

Commit 98b4a1c

Browse files
committed
Added SelectArtboardObjects
Select objects overlapping or non-overlapping active artboard with bounds tolerance
1 parent faeae79 commit 98b4a1c

File tree

5 files changed

+384
-8
lines changed

5 files changed

+384
-8
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ Many scripts are free to download thanks to user support. Help me to develop new
8484
</a>
8585

8686
## Paid scripts
87+
* [BentoGrid](https://www.buymeacoffee.com/aiscripts/e/341609) — script generates random bento grids with different cell proportions.
88+
* [RandomColors](https://www.buymeacoffee.com/aiscripts/e/332147) — script generates random fill and stroke colors for selected objects and editable text.
8789
* [ExportSequence](https://www.buymeacoffee.com/aiscripts/e/230926) — script for toggle visibility of numbered objects in selected groups and exports document as sequence to PNGs or JPGs.
8890
* [ColorToner](https://www.buymeacoffee.com/aiscripts/e/231463) — script for generating tints, shades, and tones from base colors.
8991
* [GradientBlender](https://www.buymeacoffee.com/aiscripts/e/231606) — script to make gradients more accurate, smooth.
@@ -186,6 +188,7 @@ Click the category name to learn more about the scripts in the selected category
186188
* [NamedItemsFinder](https://github.com/creold/illustrator-scripts/blob/master/md/Select.md#named-items-finder) `upd, 09.02.2024`
187189
* [SelectAllLayersAbove](https://github.com/creold/illustrator-scripts/blob/master/md/Select.md#selectalllayersabove) `21.02.2022`
188190
* [SelectAllLayersBelow](https://github.com/creold/illustrator-scripts/blob/master/md/Select.md#selectalllayersabove) `21.02.2022`
191+
* [SelectArtboardObjects](https://github.com/creold/illustrator-scripts/blob/master/md/Select.md#selectartboardobjects) `new, 30.12.2024`
189192
* [SelectBySwatches](https://github.com/creold/illustrator-scripts/blob/master/md/Select.md#selectbyswatches) `upd, 22.04.2024`
190193
* [SelectOnlyPoints](https://github.com/creold/illustrator-scripts/blob/master/md/Select.md#selectonlypoints)
191194
* [SelectPointsByType](https://github.com/creold/illustrator-scripts/blob/master/md/Select.md#selectpointsbytype) `upd, 09.02.2024`

README.ru.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,16 @@
8484
</a>
8585

8686
## Платные скрипты
87-
* [ExportSequence](https://www.buymeacoffee.com/aiscripts/e/230926) - переключает пронумерованные объекты в выбранных группах и экспортирует активный артборд в виде последовательных PNG или JPG файлов
88-
* [ColorToner](https://www.buymeacoffee.com/aiscripts/e/231463) — скрипт для генерации светлых оттенков, теней и тонов исходных цветов
89-
* [GradientBlender](https://www.buymeacoffee.com/aiscripts/e/231606) — скрипт для создания аккуратных переходов цветов в градиентах
90-
* [Ai2Ae](https://www.buymeacoffee.com/aiscripts/e/231609) — скрипт раскладывает объекты по слоям для импорта в After Effects
91-
* [ArtboardsFromCSV](https://www.buymeacoffee.com/aiscripts/e/231618) — скрипт пакетно создаёт именованные артборды с размерами, заданными в CSV таблице
92-
* [Duplicate Artboards Pro](https://www.buymeacoffee.com/aiscripts/e/231621) — скрипт создаёт заданное количество копий артбордов
93-
* [HighlightText](https://www.buymeacoffee.com/aiscripts/e/231626) — скрипт создаёт подчёркивание строк выбранных текстовых объектов
94-
* [ImportImagesByName](https://www.buymeacoffee.com/aiscripts/e/231629) — скрипт импортирует в документ изображения из папки по имени, указанному в текстовых фреймах
87+
* [BentoGrid](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1667%3FcategoryId=5705) — генерирует случайные сетки в стиле Bento UI с ячейками разных пропорций.
88+
* [RandomColors](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1666%3FcategoryId=5705) — генерирует случайные цвета для заливок и обводок выбранных объектов или текстов.
89+
* [ExportSequence](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1665%3FcategoryId=5705) - переключает пронумерованные объекты в выбранных группах и экспортирует активный артборд в виде последовательных PNG или JPG файлов
90+
* [ColorToner](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1653%3FcategoryId=5705) — скрипт для генерации светлых оттенков, теней и тонов исходных цветов
91+
* [GradientBlender](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1661%3FcategoryId=5705) — скрипт для создания аккуратных переходов цветов в градиентах
92+
* [Ai2Ae](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1659%3FcategoryId=5705) — скрипт раскладывает объекты по слоям для импорта в After Effects
93+
* [ArtboardsFromCSV](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1662%3FcategoryId=5705) — скрипт пакетно создаёт именованные артборды с размерами, заданными в CSV таблице
94+
* [Duplicate Artboards Pro](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1660%3FcategoryId=5705) — скрипт создаёт заданное количество копий артбордов
95+
* [HighlightText](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1663%3FcategoryId=5705) — скрипт создаёт подчёркивание строк выбранных текстовых объектов
96+
* [ImportImagesByName](https://aiscripts.robo.market/#modalProductsByCategories_2_5705_1664%3FcategoryId=5705) — скрипт импортирует в документ изображения из папки по имени, указанному в текстовых фреймах
9597

9698
## Категории
9799
Нажмите на название категории, чтобы перейти к описанию и демонстрациям её скриптов.
@@ -195,6 +197,7 @@
195197
* [NamedItemsFinder](https://github.com/creold/illustrator-scripts/blob/master/md/Select.ru.md#named-items-finder) `upd, 09.02.2024`
196198
* [SelectAllLayersAbove](https://github.com/creold/illustrator-scripts/blob/master/md/Select.ru.md#selectalllayersabove) `21.02.2022`
197199
* [SelectAllLayersBelow](https://github.com/creold/illustrator-scripts/blob/master/md/Select.ru.md#selectalllayersabove) `21.02.2022`
200+
* [SelectArtboardObjects](https://github.com/creold/illustrator-scripts/blob/master/md/Select.ru.md#selectartboardobjects) `new, 30.12.2024`
198201
* [SelectBySwatches](https://github.com/creold/illustrator-scripts/blob/master/md/Select.ru.md#selectbyswatches) `upd, 22.04.2024`
199202
* [SelectOnlyPoints](https://github.com/creold/illustrator-scripts/blob/master/md/Select.ru.md#selectonlypoints)
200203
* [SelectPointsByType](https://github.com/creold/illustrator-scripts/blob/master/md/Select.ru.md#selectpointsbytype) `upd, 09.02.2024`

jsx/SelectArtboardObjects.jsx

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
/*
2+
SelectArtboardObjects.jsx for Adobe Illustrator
3+
Select objects overlapping or non-overlapping active artboard with bounds tolerance
4+
Author: Sergey Osokin, email: [email protected]
5+
6+
Installation: https://github.com/creold/illustrator-scripts#how-to-run-scripts
7+
8+
Release notes:
9+
0.1 Initial version
10+
11+
Donate (optional):
12+
If you find this script helpful, you can buy me a coffee
13+
- via Buymeacoffee: https://www.buymeacoffee.com/aiscripts
14+
- via Donatty https://donatty.com/sergosokin
15+
- via DonatePay https://new.donatepay.ru/en/@osokin
16+
- via YooMoney https://yoomoney.ru/to/410011149615582
17+
18+
NOTICE:
19+
Tested with Adobe Illustrator CC 2019-2025 (Mac/Win).
20+
This script is provided "as is" without warranty of any kind.
21+
Free to use, not for sale
22+
23+
Released under the MIT license
24+
http://opensource.org/licenses/mit-license.php
25+
26+
Check my other scripts: https://github.com/creold
27+
*/
28+
29+
//@target illustrator
30+
app.preferences.setBooleanPreference('ShowExternalJSXWarning', false); // Fix drag and drop a .jsx file
31+
32+
function main() {
33+
var SCRIPT = {
34+
name: 'Select Artboard Objects',
35+
version: 'v0.1'
36+
};
37+
38+
var CFG = {
39+
tolerance: 1, // Default tolerance
40+
units: getUnits(),
41+
aiVers: parseFloat(app.version),
42+
isMac: /mac/i.test($.os)
43+
};
44+
45+
if (!/illustrator/i.test(app.name)) {
46+
alert('Wrong application\nRun script from Adobe Illustrator', 'Script error');
47+
return;
48+
}
49+
50+
if (parseFloat(app.version) < 16) {
51+
alert('Wrong app version\nSorry, script only works in Illustrator CS6 and later', 'Script error');
52+
return false;
53+
}
54+
55+
if (!documents.length) {
56+
alert('No documents\nOpen a document and try again', 'Script error');
57+
return;
58+
}
59+
60+
var doc = app.activeDocument;
61+
var idx = doc.artboards.getActiveArtboardIndex();
62+
var abBnds = doc.artboards[idx].artboardRect;
63+
64+
// Scale factor for Large Canvas mode
65+
CFG.sf = doc.scaleFactor ? doc.scaleFactor : 1;
66+
67+
// DIALOG
68+
var win = new Window('dialog', SCRIPT.name + ' ' + SCRIPT.version);
69+
win.orientation = 'column';
70+
win.alignChildren = ['fill', 'center'];
71+
72+
win.add('statictext', undefined, 'Artboard: ' + doc.artboards[idx].name.slice(0, 16));
73+
74+
// AREA
75+
var overlapPnl = win.add('panel', undefined, 'Which objects to select');
76+
overlapPnl.orientation = 'column';
77+
overlapPnl.alignChildren = ['fill', 'center'];
78+
overlapPnl.margins = [10, 15, 10, 7];
79+
80+
var isOverlapRb = overlapPnl.add('radiobutton', undefined, 'All Inside Artboard');
81+
isOverlapRb.value = true;
82+
var isNonOverlapRb = overlapPnl.add('radiobutton', undefined, 'All Outside Artboard');
83+
84+
if (CFG.isMac || CFG.aiVers >= 26.4 || CFG.aiVers <= 17) {
85+
isOverlapRb.active = true;
86+
}
87+
88+
// TOLERANCE
89+
var tolPnl = win.add('panel', undefined, 'Artboard Tolerance, ' + CFG.units);
90+
tolPnl.orientation = 'row';
91+
tolPnl.alignChildren = ['fill', 'center'];
92+
tolPnl.margins = [10, 15, 10, 7];
93+
94+
var tolInp = tolPnl.add('edittext', undefined, CFG.tolerance);
95+
tolInp.characters = 6;
96+
97+
// BUTTONS
98+
var btns = win.add('group');
99+
btns.alignChildren = ['fill', 'fill'];
100+
101+
var cancel = btns.add('button', undefined, 'Cancel', { name: 'cancel' });
102+
var ok = btns.add('button', undefined, 'Ok', { name: 'ok' });
103+
104+
var copyright = win.add('statictext', undefined, '\u00A9 Sergey Osokin. Visit Github');
105+
copyright.justify = 'center';
106+
107+
cancel.onClick = win.close;
108+
109+
ok.onClick = function () {
110+
var tolerance = convertUnits(parseFloat(tolInp.text), CFG.units, 'px' ) / CFG.sf;
111+
// Check numeric tolerance
112+
if (isNaN(tolerance)) {
113+
alert('Incorrect tolerance\nEnter numeric value', 'Script error');
114+
return;
115+
}
116+
// Invert tolerance value
117+
if (isOverlapRb.value) tolerance *= -1;
118+
119+
ok.text = 'Wait...';
120+
121+
app.executeMenuCommand('selectall');
122+
app.redraw();
123+
124+
var items = getItems(app.selection);
125+
126+
app.executeMenuCommand('deselectall');
127+
app.selection = null;
128+
129+
var overlapArr = [];
130+
var nonOverlapArr = [];
131+
132+
for (var i = items.length - 1; i >= 0; i--) {
133+
var itemBnds = getVisibleBounds(items[i], 'geometricBounds');
134+
if (isOverlap(itemBnds, abBnds, tolerance)) {
135+
overlapArr.push(items[i]);
136+
} else {
137+
nonOverlapArr.push(items[i]);
138+
}
139+
}
140+
141+
app.selection = isOverlapRb.value ? overlapArr : nonOverlapArr;
142+
143+
win.close();
144+
}
145+
146+
copyright.addEventListener('mousedown', function () {
147+
openURL('https://github.com/creold');
148+
});
149+
150+
win.center();
151+
win.show();
152+
}
153+
154+
/**
155+
* Get active document ruler units
156+
* @returns {string} - Shortened units
157+
*/
158+
function getUnits() {
159+
if (!documents.length) return '';
160+
var key = activeDocument.rulerUnits.toString().replace('RulerUnits.', '');
161+
switch (key) {
162+
case 'Pixels': return 'px';
163+
case 'Points': return 'pt';
164+
case 'Picas': return 'pc';
165+
case 'Inches': return 'in';
166+
case 'Millimeters': return 'mm';
167+
case 'Centimeters': return 'cm';
168+
// Added in CC 2023 v27.1.1
169+
case 'Meters': return 'm';
170+
case 'Feet': return 'ft';
171+
case 'FeetInches': return 'ft';
172+
case 'Yards': return 'yd';
173+
// Parse new units in CC 2020-2023 if a document is saved
174+
case 'Unknown':
175+
var xmp = activeDocument.XMPString;
176+
if (/stDim:unit/i.test(xmp)) {
177+
var units = /<stDim:unit>(.*?)<\/stDim:unit>/g.exec(xmp)[1];
178+
if (units == 'Meters') return 'm';
179+
if (units == 'Feet') return 'ft';
180+
if (units == 'FeetInches') return 'ft';
181+
if (units == 'Yards') return 'yd';
182+
return 'px';
183+
}
184+
break;
185+
default: return 'px';
186+
}
187+
}
188+
189+
/**
190+
* Convert a value from one set of units to another
191+
* @param {string} value - The numeric value to be converted
192+
* @param {string} currUnits - The current units of the value (e.g., 'in', 'mm', 'pt')
193+
* @param {string} newUnits - The desired units for the converted value (e.g., 'in', 'mm', 'pt')
194+
* @returns {number} - The converted value in the specified units
195+
*/
196+
function convertUnits(value, currUnits, newUnits) {
197+
return UnitValue(value, currUnits).as(newUnits);
198+
}
199+
200+
/**
201+
* Get items from an Adobe Illustrator collection, including nested pageItems.
202+
* @param {Object} coll - The Adobe Illustrator collection to retrieve items from
203+
* @returns {Array} result - Return a JavaScript Array containing relevant items from the given collection
204+
*/
205+
function getItems(coll) {
206+
var results = [];
207+
for (var i = 0; i < coll.length; i++) {
208+
var item = coll[i];
209+
if (!item.editable) continue;
210+
if (item.pageItems && item.pageItems.length) {
211+
results = [].concat(results, getItems(item.pageItems));
212+
} else {
213+
results.push(item);
214+
}
215+
}
216+
return results;
217+
}
218+
219+
/**
220+
* Get the actual "visible" bounds
221+
* https://github.com/joshbduncan/illustrator-scripts/blob/main/jsx/DrawVisibleBounds.jsx
222+
* @param {Object} obj - The target object
223+
* @param {string} type - The object bounds type
224+
* @returns {Array} - An array representing the actual bounds
225+
*/
226+
function getVisibleBounds(obj, type) {
227+
if (arguments.length == 1 || type == undefined) type = 'geometricBounds';
228+
var doc = app.activeDocument;
229+
var bnds, clippedItem, tmpItem, tmpLayer;
230+
var curItem;
231+
if (obj.typename === 'GroupItem') {
232+
if (obj.clipped) {
233+
// Check all sub objects to find the clipping path
234+
for (var i = 0; i < obj.pageItems.length; i++) {
235+
curItem = obj.pageItems[i];
236+
if (curItem.clipping) {
237+
clippedItem = curItem;
238+
break;
239+
} else if (curItem.typename === 'CompoundPathItem') {
240+
if (!curItem.pathItems.length) {
241+
// Catch compound path items with no pathItems
242+
// via William Dowling @ github.com/wdjsdev
243+
tmpLayer = doc.layers.add();
244+
tmpItem = curItem.duplicate(tmpLayer);
245+
app.executeMenuCommand('deselectall');
246+
tmpItem.selected = true;
247+
app.executeMenuCommand('noCompoundPath');
248+
tmpLayer.hasSelectedArtwork = true;
249+
app.executeMenuCommand('group');
250+
clippedItem = item[0];
251+
break;
252+
} else if (curItem.pathItems[0].clipping) {
253+
clippedItem = curItem;
254+
break;
255+
}
256+
}
257+
}
258+
if (!clippedItem) clippedItem = obj.pageItems[0];
259+
bnds = clippedItem[type];
260+
if (tmpLayer) {
261+
tmpLayer.remove();
262+
tmpLayer = undefined;
263+
}
264+
} else {
265+
// If the object is not clipped
266+
var subObjBnds;
267+
var allBoundPoints = [[], [], [], []];
268+
// Get the bounds of every object in the group
269+
for (var i = 0; i < obj.pageItems.length; i++) {
270+
curItem = obj.pageItems[i];
271+
subObjBnds = getVisibleBounds(curItem, type);
272+
allBoundPoints[0].push(subObjBnds[0]);
273+
allBoundPoints[1].push(subObjBnds[1]);
274+
allBoundPoints[2].push(subObjBnds[2]);
275+
allBoundPoints[3].push(subObjBnds[3]);
276+
}
277+
// Determine the groups bounds from it sub object bound points
278+
bnds = [
279+
Math.min.apply(Math, allBoundPoints[0]),
280+
Math.max.apply(Math, allBoundPoints[1]),
281+
Math.max.apply(Math, allBoundPoints[2]),
282+
Math.min.apply(Math, allBoundPoints[3]),
283+
];
284+
}
285+
} else {
286+
bnds = obj[type];
287+
}
288+
return bnds;
289+
}
290+
291+
/**
292+
* Determine whether two bounding boxes overlap, within a specified tolerance
293+
* @param {Array} bnds1 - The first bounding box represented as an array of four numbers [left, top, right, bottom]
294+
* @param {Array} bnds2 - The second bounding box represented as an array of four numbers [left, top, right, bottom]
295+
* @param {number} t - The tolerance value to use when checking for overlap
296+
* @returns {boolean} - True if the bounding boxes overlap, false otherwise
297+
*/
298+
function isOverlap(bnds1, bnds2, t) {
299+
if ((bnds1[2] <= bnds2[0] + t || bnds1[0] >= bnds2[2] - t) ||
300+
(bnds1[3] >= bnds2[1] - t || bnds1[1] <= bnds2[3] + t)) {
301+
return false;
302+
} else {
303+
return true;
304+
}
305+
}
306+
307+
/**
308+
* Open a URL in the default web browser
309+
* @param {string} url - The URL to open in the web browser
310+
* @returns {void}
311+
*/
312+
function openURL(url) {
313+
var html = new File(Folder.temp.absoluteURI + '/aisLink.html');
314+
html.open('w');
315+
var htmlBody = '<html><head><META HTTP-EQUIV=Refresh CONTENT="0; URL=' + url + '"></head><body> <p></body></html>';
316+
html.write(htmlBody);
317+
html.close();
318+
html.execute();
319+
}
320+
321+
// Run script
322+
try {
323+
main();
324+
} catch (err) {}

0 commit comments

Comments
 (0)