Copy link to clipboard
Copied
Hello folks,
In a recent post (https://community.adobe.com/t5/illustrator/script-insert-text-number-in-the-middle-of-visible-bounds...) I was reading on the following matter: the author uploaded a script that groups filled paths by color for paintings by numbers. However, when I tried to apply it to my Illustrator, it didn't work. Instead of showing different numbers in each field, I only get one and the same number.
I would appreciate it if someone could help me with a new, working script. I am also willing to pay for one.
Cheers.
Hi,
Another version of the script. This is handling just pathItems and CMYK colors. You can test it for simple sneario. This is not final and clean version. Code reference from the same link that you have shared
#target illustrator
var doc = app.activeDocument;
function main() {
var _pageItems = doc.pageItems;
var _layersCollection = [];
for (var p = 0; p < _pageItems.length; p++) {
collectItemsBasedOnColors(_pageItems[p], _layersCollection);
}
lays = doc.
...
Copy link to clipboard
Copied
Hi,
Another version of the script. This is handling just pathItems and CMYK colors. You can test it for simple sneario. This is not final and clean version. Code reference from the same link that you have shared
#target illustrator
var doc = app.activeDocument;
function main() {
var _pageItems = doc.pageItems;
var _layersCollection = [];
for (var p = 0; p < _pageItems.length; p++) {
collectItemsBasedOnColors(_pageItems[p], _layersCollection);
}
lays = doc.layers;
WORK_LAY = lays.add();
NUM_LAY = lays.add();
for (var l = 0; l < _layersCollection.length; l++) {
process(_layersCollection[l].pathItems, false, (l + 1));
}
}
function process(items, isCompound, _num) {
var j = 0,
b, xy, s, p, op;
for (; j < items.length; j++) {
// process each pathItem
op = items[j];
// add stroke
if (isCompound) {
strokeComPath(op);
} else {
!op.closed && op.closed = true;
op.filled = false;
op.stroked = true;
};
b = getCenterBounds(op);
xy = [b[0] + (b[2] - b[0]) / 2, b[1] + (b[3] - b[1]) / 2];
s = (
Math.min(op.height, op.width) < 20 ||
(op.area && Math.abs(op.area) < 150)
) ? 4 : 6; // adjust font size for small area paths.
add_nums(_num, xy, s);
}
}
function collectItemsBasedOnColors(myCurrentObject, _layersCollection) {
var myLayerName = "Unknown";
if (myCurrentObject.typename == "PathItem") {
if (myCurrentObject.filled == true) {
if (myCurrentObject.fillColor == "[CMYKColor]") {
myLayerName = "CMYK: " + Math.round(myCurrentObject.fillColor.cyan) + "," + Math.round(myCurrentObject.fillColor.magenta) + "," + Math.round(myCurrentObject.fillColor.yellow) + "," + Math.round(myCurrentObject.fillColor.black);
}
}
try {
var _layer = doc.layers.getByName(myLayerName);
myCurrentObject.move(_layer, ElementPlacement.PLACEATBEGINNING);
}
catch (e) {
var _layer = doc.layers.add()
_layer.name = myLayerName
myCurrentObject.move(_layer, ElementPlacement.PLACEATBEGINNING);
_layersCollection.push(_layer);
}
}
}
function getCenterBounds(op) {
var originalMinSize = getMinVisibleSize(op.visibleBounds);
var p = applyOffset(op, false);
if (getMinVisibleSize(p.visibleBounds) > originalMinSize) {
// in some cases, path p becomes larger for some unknown reason
p.remove();
p = applyOffset(op, true);
}
var b = p.visibleBounds;
if (getMinVisibleSize(b) > 10) {
activeDocument.selection = [p];
executeMenuCommand("expandStyle");
p = activeDocument.selection[0];
if (p.typename == "CompoundPathItem") {
b = findBestBounds(op, p);
}
}
p.remove();
return b;
}
function getMinVisibleSize(b) {
var s = Math.min(b[2] - b[0], b[1] - b[3]);
return Math.abs(s);
}
function add_nums(n, xy, s) {
var txt = NUM_LAY.textFrames.add();
txt.contents = n;
txt.textRange.justification = Justification.CENTER;
txt.textRange.characterAttributes.size = s;
txt.position = [xy[0] - txt.width / 2, xy[1] + txt.height / 2];
}
function applyOffset(op, checkBounds) {
var p = op.duplicate(WORK_LAY, ElementPlacement.PLACEATBEGINNING),
// offset value the small the better, but meantime more slow.
offset = function () {
var minsize = Math.min(p.width, p.height);
if (minsize >= 50) {
return '-1'
} else if (20 < minsize && minsize < 50) {
return '-0.5'
} else {
return '-0.2' // 0.2 * 2 (both side ) * 50 (Times) = 20
}
},
xmlstring = '<LiveEffect name="Adobe Offset Path"><Dict data="I jntp 2 R mlim 4 R ofst #offset"/></LiveEffect>'
.replace('#offset', offset()),
TIMES = 100; // if shapes are too large, should increase the value.
if (checkBounds) {
// check its size only if it needs, because it's too slow
while (TIMES-- && getMinVisibleSize(p.visibleBounds) > 3) p.applyEffect(xmlstring);
} else {
while (TIMES--) p.applyEffect(xmlstring);
}
return p;
}
function getGeometricCenter(p) {
var b = p.geometricBounds;
return [(b[0] + b[2]) / 2, (b[1] + b[3]) / 2];
}
// returns square of distance between p1 and p2
function getDist2(p1, p2) {
return Math.pow(p1[0] + p2[0], 2) + Math.pow(p1[1] + p2[1], 2);
}
// returns visibleBounds of a path in a compoundPath p
// which is closest to center of the original path op
function findBestBounds(op, p) {
var opc = getGeometricCenter(op);
var idx = 0,
d;
var minD = getDist2(opc, getGeometricCenter(p.pathItems[0]));
for (var i = 0, iEnd = p.pathItems.length; i < iEnd; i++) {
d = getDist2(opc, getGeometricCenter(p.pathItems[i]));
if (d < minD) {
minD = d;
idx = i;
}
}
return p.pathItems[idx].visibleBounds;
}
main();
Running with attached sample file. Ofcourse more can be done to handle other scenarios.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Just updated the code, keep following line
var doc = app.activeDocument;
out the main() function.
Copy link to clipboard
Copied
When I try the updated code the same error pops-up as before.
Copy link to clipboard
Copied
How are you executing the code? Are you using extended toolkit?
Copy link to clipboard
Copied
I load the code directly from illustrator.
Copy link to clipboard
Copied
I tried in this way as well, and it is running successfully.
Did you save your code with .jsx extension?
Copy link to clipboard
Copied
I tried the script on this thread in CS6 and it seems to be working fine for me. (Thank you, Charu.)
Copy link to clipboard
Copied
Thanks femkeblanco for confirming 🙂
Copy link to clipboard
Copied
I would like the script to show the numbers from 1 to 9 and then to start to show letters: "A,B,C..." and so on. So, for example - 1,2,3,4,5,6,7,8,9,A,B,C,D...etc.
Copy link to clipboard
Copied
Hello folks,
Can someone of you please help me with a code I need for Illustrator?
I'm working with paintings by numbers and would like the script to show the numbers from 1 to 9 and then to start to show letters: "A,B,C..." and so on. So, for example - 1,2,3,4,5,6,7,8,9,A,B,C,D...etc.
Any help would greatly be appreciated.
Copy link to clipboard
Copied
Replace the line (which is line 100 in the above script)
txt.contents = n;
with these two lines
var x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
txt.contents = x[n];
The script will fail if you go beyond "Z".
Copy link to clipboard
Copied
Thank you very nice.
Copy link to clipboard
Copied
hi there please could I have the link to download this script also. it would be much appreciated
Copy link to clipboard
Copied
there's no download link, the script is posted here in response #1 by Charu. You have to copy/paste in a blank text file and save it with any name, but change the extension to jsx
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi all folks,
I get the following error, does anyone knows how can I fix it?
Error 1200: an illustrator error occurred: 1246458189 ('MRAP')
Line:128
-> while (TIMES--) p.applyEffect(xmlstring);
Thank you in advance
Copy link to clipboard
Copied
Copy link to clipboard
Copied
It's not working with compound paths 😞
Copy link to clipboard
Copied
It was never intended to. Compound Paths can have multiple fills within their children paths, and you wouldn't be able to group those children paths with other paths without breaking the compound.
Copy link to clipboard
Copied
Hello. What can be done in this script to put more than one number depending on the area of the object?
For example like this!