Copy link to clipboard
Copied
Hello again, my first CEP panel is a responsive Color History and not much but I'm really surprised by the results -- I'm not a programmer and never thought I could code. I'm going to rebuild it to really shine in Illustrator (because it's my favorite) and thought a cool feature might be (on mouse hover over the swatches) revealing where recent colors were used by dimming all other colors of any kind of objects, like this:
But right now it's crude because I'm toggling the entire object's (pathItem, textFrames) opacity, so not accounting for having both a stroke and a fill or multiples of either:
I noticed that it only recognizes the bottom-most stroke and fill in your Appearance Panel, and was surprised that something like .strokeColor[1] didn't work. Ideally in the above, the strokes and fills shouldn't dim if "highlighting" (/discriminating all objects against) their respective colors, which is a Recent Colors swatch in the screen recording at the top. I know I can use pathItems.stroked and pathItems.filled to check whether it has a stroke or fill (or both), but I don't know how I'd dim only one of them once I know. This seems like something that should be in the DOM? strokeOpacity and fillOpacity? Or additional strokes and fills as array items? If I could use RGBA colors (where A is alpha/transparency) that'd work, I figure I could also follow SillyV's post on doScript() dynamic actions​ since a recording an opacity change for stroke/fill will correctly play them, but that seems like an awfully hacky solution to this and I'd rather not glitch the selection box display since this is purely aesthetic and a playful exercise in vanity.
Is this possible? I'm using RGB color space and storing the color data in an array with hex values right now, but I don't have to. My current code is:
var doc = app.activeDocument
var isFill = app.isFillActive();
var exist = app.documents.length > 0;
var hasPaths = doc.pathItems.length > 0;
var allPaths = doc.pathItems.length;
var allTexts = doc.textFrames.length;
var prevOpacityTexts = [];
var prevOpacityPaths = [];
function lowerOpacity(exceptThis) {
if (exist && hasPaths) {
while (prevOpacityPaths.length > 0) {
prevOpacityPaths.pop();
}
while (prevOpacityTexts.length > 0) {
prevOpacityTexts.pop();
}
// Path Items
for (var index = 0; index < allPaths; index++) {
prevOpacityPaths.push(doc.pathItems[index].opacity)
if (rgbActiveHex("pathItems", index) === exceptThis) {
doc.pathItems[index].opacity = 100;
} else {
doc.pathItems[index].opacity = 20;
}
}
// Text frames
for (var index = 0; index < allTexts; index++) {
prevOpacityTexts.push(doc.textFrames[index].opacity)
if (rgbActiveHex("textFrames", index) === exceptThis) {
doc.textFrames[index].opacity = 100;
} else {
doc.textFrames[index].opacity = 20;
}
}
//
}
}
function returnOpacity() {
if (exist && hasPaths) {
for (var index = 0; index < allPaths; index++) {
var previous = prevOpacityPaths[index];
doc.pathItems[index].opacity = prevOpacityPaths[index];
}
for (var index = 0; index < allTexts; index++) {
var previous = prevOpacityTexts[index];
doc.textFrames[index].opacity = prevOpacityTexts[index];
}
}
}
function rgbActiveHex(type, here) {
var activeObject;
if (type === "pathItems") {
if ((doc.pathItems[here].stroked) && !(doc.pathItems[here].filled)) {
activeObject = doc.pathItems[here].strokeColor
} else if ((doc.pathItems[here].filled) && !(doc.pathItems[here].stroked)) {
activeObject = doc.pathItems[here].fillColor
} else {
//
}
} else if (type === "textFrames") {
activeObject = doc.textFrames[here].textRange.characterAttributes.fillColor
}
var convertColor = rgbToHex(activeObject.red, activeObject.green, activeObject.blue);
return convertColor;
}
/// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
// componentToHex(c);
// rgbToHex(r, g, b);
// hexToRgb(hex);
Copy link to clipboard
Copied
Okay, so now you hit the scripting wall as you can't do anything to affect current items in appearance panel directly like you need.
You may be able to figure out the apply Live effect XML feature, but that's limited still.
You may need to dive deep into the SDK and make a plugin to work with your extension.
I may elaborate more later if someone doesn't chime in to explain further with links.
Cause right now I got to run.
Copy link to clipboard
Copied
I'm not afraid of walls, sir. Admittedly I'm a bit disappointed that the ceiling is so low because I expected multiple fills and strokes to be common enough to include, but I don't mind trying new things. Will you check out my current Color History​​? I'm really happy with it but I'd love to take it further, if the coding weren't so sloppy then I'd share but I'd rather rebuild it first and include After Effects and I/O. The highlighting example of this thread is meant to show where in the artwork that recent color is used when inside AI.
I'll look into the options you mentioned here. Is this not possible to do through Actions or duplication? Can I select objects without the selection box being displayed? Is my only "real" option to literally build my own plugin, extending the API in order to access these? I've no experience with C++ yet.
Copy link to clipboard
Copied
Yea I'm ahead with C++ experience than you are by a factor of zero.
But unfortunately, yes, the features inaccessible via script, you have to kind-of build your own access to and then you can call your plugin features from the high-level scripting .jsx files via the app.sendScriptMessage() function.
Copy link to clipboard
Copied
yes, the bar is very low, there's no access to appearance panel features. I think the color reported is the active color in the appearance panel, not necessarily the bottom one. But still, we don't have options to selecting the top most color.
duplicating might be your only option. I'm not sure if it will be efficient but worth trying. Duplicate the object, expand appearance in case of multiple strokes/fills, copy fill, no stroke. then duplicate again copy stroke, no fill.
to answer your other question, yes, you can select items without showing, by Hiding Edges and Hiding Bounding Box.
Copy link to clipboard
Copied
It'd be really cool to do this in a bulletproof way, accounting for any number of elements inside the appearance panel and toggling their transparency. Haven't tried duplicating or actions yet, right now it's still at the level of checking for single strokes/fills. Won't do both stroke and fill, won't recognize content inside clipping masks or Live Paint.