Copy link to clipboard
Copied
Hi all -
I'm working on extending a script someone has made that assigns random colors (within user parameters) to the fill and/or stroke of selected objects.
Currently, to set the parameters for the Hue, the script uses two input boxes to enter values from 0-255, indicating the range of hues the script uses. I'd like to have some way to visually indicate the hue range selected, to assist those who might not have the hue spectrum memorized. 🙂
First thought was to use a hue spectrum image, with two sliders underneath to select the range, but I couldn't find any documentation for using two indicators on the same slider (like in Photoshop's "Blend if" sliders in Layer options).
Second thought was to use the input boxes, and draw a rectangle above them in the dialog that's filled with a gradient ranging from the start to end values (and update it by redrawing each time the values are changed)
However, the latest ScriptUI documentation doesn't show a gradient as an option for drawing with ScriptUIPath, only solid fills of a rectangle with the Brush, for example.
Anyone know of a way to create a gradient fill inside a ScriptUI window? Failing that, I'm thinking my best bet is to generate a series of small rectangles in a line, and fill each with an appropriate hue to create a rough "gradient" effect, but that's not ideal.
Thanks in advance!
Okay I took a little break to do this exercise. Here's a function that makes the gradient array blend and then a couple of other functions to test that resulting array in an AI document as well as the ScriptUI canvas graphics.
One difference is the pathItems.rectangle() function takes (y, x, width, height), the scriptUI .rectPath() function is actually (x, y, width, height)
...#target illustrator
function test() {
function makeRGBGradientArray(color_1, color_2, steps) {
var arr = [];
var thisArr;
fo
Copy link to clipboard
Copied
First thought was to use a hue spectrum image, with two sliders underneath to select the range, but I couldn't find any documentation for using two indicators on the same slider (like in Photoshop's "Blend if" sliders in Layer options).
Among any hacky workarounds for having a range slider, perhaps it could be possible to stack two sliders on top of each other and see if the indicator on the bottom slider is not completely blocked to allow a clickable area for changing it.
But really, since ScriptUI does provide a basic canvas-drawing function, you can draw your entire slider and gradient with drawing functions. I wish I could provide a code sample which could even verify if this approach would work, but unfortunately too busy at the moment.
Copy link to clipboard
Copied
Okay I took a little break to do this exercise. Here's a function that makes the gradient array blend and then a couple of other functions to test that resulting array in an AI document as well as the ScriptUI canvas graphics.
One difference is the pathItems.rectangle() function takes (y, x, width, height), the scriptUI .rectPath() function is actually (x, y, width, height)
#target illustrator
function test() {
function makeRGBGradientArray(color_1, color_2, steps) {
var arr = [];
var thisArr;
for (var i = 0; i < steps; i++) {
thisArr = [];
thisArr[0] = (((color_2[0] - color_1[0]) / steps) * i) + color_1[0];
thisArr[1] = (((color_2[1] - color_1[1]) / steps) * i) + color_1[1];
thisArr[2] = (((color_2[2] - color_1[2]) / steps) * i) + color_1[2];
arr.push(thisArr);
}
return arr;
};
function drawGradientInAI(gradArr) {
var thisArr;
var thisColor;
var doc = app.activeDocument;
var yPos = 0;
var xPos = 0;
var width = 10;
var height = 40;
var newRect;
for (var i = 0; i < gradArr.length; i++) {
thisArr = gradArr;
thisColor = new RGBColor();
thisColor.red = Math.round(thisArr[0]);
thisColor.green = Math.round(thisArr[1]);
thisColor.blue = Math.round(thisArr[2]);
newRect = doc.pathItems.rectangle(yPos, xPos, width, height);
newRect.fillColor = thisColor;
xPos += width;
}
};
function drawGradientInScriptUI(gradArr, canvasArea) {
var canvas = canvasArea.graphics;
var yPos = 0;
var xPos = 0;
var width = 10;
var height = 40;
var thisArr;
for (var i = 0; i < gradArr.length; i++) {
thisArr = gradArr;
thisArr[0] = (thisArr[0] / 255).toFixed(2) * 1;
thisArr[1] = (thisArr[1] / 255).toFixed(2) * 1;
thisArr[2] = (thisArr[2] / 255).toFixed(2) * 1;
canvas.newPath();
canvas.rectPath(xPos, yPos, width, height);
var myBrush = canvas.newBrush(canvas.BrushType.SOLID_COLOR, [thisArr[0], thisArr[1], thisArr[2]]);
canvas.fillPath(myBrush);
canvas.closePath();
xPos += width;
}
};
var color_1 = [255, 0, 0];
var color_2 = [255, 255, 0];
// drawGradientInAI(makeRGBGradientArray(color_1, color_2, 20));
var w = new Window("dialog", "Test");
var p = w.add("panel");
p.size = [200, 200];
p.onDraw = function() {
drawGradientInScriptUI(makeRGBGradientArray(color_1, color_2, 20), this);
};
w.show();
};
test();
Copy link to clipboard
Copied
And now if we add some code for the sliders, the result ends up pretty cool! I'd say exactly what you're looking for, if I am not mistaken! (well, the drawing and ScriptUI graphics updating part)
var w = new Window("dialog", "Test");
var p = w.add("panel");
p.size = [200, 100];
p.onDraw = function(){
drawGradientInScriptUI(makeRGBGradientArray(color_1, color_2, 20), this);
};
var g_sliders = w.add("group");
var g_sliders_1 = w.add("group");
var g_sliders_2 = w.add("group");
var slider_1_r = g_sliders_1.add("slider");
slider_1_r.minvalue = 0;
slider_1_r.maxvalue = 255;
var slider_1_g = g_sliders_1.add("slider");
slider_1_g.minvalue = 0;
slider_1_g.maxvalue = 255;
var slider_1_b = g_sliders_1.add("slider");
slider_1_b.minvalue = 0;
slider_1_b.maxvalue = 255;
var slider_2_r = g_sliders_2.add("slider");
slider_2_r.minvalue = 0;
slider_2_r.maxvalue = 255;
var slider_2_g = g_sliders_2.add("slider");
slider_2_g.minvalue = 0;
slider_2_g.maxvalue = 255;
var slider_2_b = g_sliders_2.add("slider");
slider_2_b.minvalue = 0;
slider_2_b.maxvalue = 255;
slider_1_r.onChanging = slider_1_g.onChanging = slider_1_b.onChanging = slider_2_r.onChanging = slider_2_g.onChanging = slider_2_b.onChanging = function(){
color_1 = [slider_1_r.value, slider_1_g.value, slider_1_b.value];
color_2 = [slider_2_r.value, slider_2_g.value, slider_2_b.value];
p.hide();
p.show();
};
w.show();
Copy link to clipboard
Copied
Obtain a finer display over the gradient strip by taking the width down to 1 pixel and the steps to over 200:
Copy link to clipboard
Copied
Awesome!!
Copy link to clipboard
Copied
DO you perhaps have good links of the ScripUI? I remember this very old site with data from Peter Kahrel which had/has a PDF. But its like ancient info i believe. It is called "ScriptUI for Dummies". I found it here on CreativePro. I think i also found a different version with some other info
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Yes i know that one and its amazing! I use this for quick mockups and stuff
Im interested in the UI and options available for the panels. Lots of that is hidden on the web. Adobe hardly shows any of this. I believe that PDF by Peter Kahrel also states that. That was already 10 years ago.
Copy link to clipboard
Copied
Except for a chapter in the "JavaScript Tools Guide", that's it. Seeing how little attention scripting (particularly Illustrator scripting) seems to receive, it's amazing there's anything out there at all.
Copy link to clipboard
Copied
For those interest, i got the script working agian. Hope it keeps working now.
Ive also updated the UI a bit, rearranged it and added labels. The sliders also now start in the correct position according to colors_1 and colors_2
// Panel dialog with drawGradientInScriptUI
// Author: Silly-value
// Source: https://community.adobe.com/t5/illustrator/draw-gradient-in-scriptui-panel/m-p/9517915
// function is actually(x, y, width, height)
// #target illustrator
function callDialog() {
var color_1 = [255, 0, 0];
var color_2 = [255, 255, 0];
function makeRGBGradientArray(color_1, color_2, steps) {
var arr = [];
var thisArr;
for (var i = 0; i < steps; i++) {
thisArr = [];
thisArr[0] = (((color_2[0] - color_1[0]) / steps) * i) + color_1[0];
thisArr[1] = (((color_2[1] - color_1[1]) / steps) * i) + color_1[1];
thisArr[2] = (((color_2[2] - color_1[2]) / steps) * i) + color_1[2];
arr.push(thisArr);
}
return arr;
};
function drawGradientInAI(gradArr) {
var thisArr;
var thisColor;
var doc = app.activeDocument;
var yPos = 0;
var xPos = 0;
var width = 10;
var height = 40;
var newRect;
for (var i = 0; i < gradArr.length; i++) {
thisArr = gradArr;
thisColor = new RGBColor();
thisColor.red = Math.round(thisArr[i][0]);
thisColor.green = Math.round(thisArr[i][1]);
thisColor.blue = Math.round(thisArr[i][2]);
newRect = doc.pathItems.rectangle(yPos, xPos, width, height);
newRect.fillColor = thisColor;
xPos += width;
}
};
function drawGradientInScriptUI(gradArr, canvasArea) {
var canvas = canvasArea.graphics;
var yPos = 0;
var xPos = 0;
var width = 13;
var height = 40;
var thisArr;
for (var i = 0; i < gradArr.length; i++) {
thisArr = gradArr[i];
thisArr[0] = (thisArr[0] / 255).toFixed(2) * 1;
thisArr[1] = (thisArr[1] / 255).toFixed(2) * 1;
thisArr[2] = (thisArr[2] / 255).toFixed(2) * 1;
canvas.newPath();
canvas.rectPath(xPos, yPos, width, height);
var myBrush = canvas.newBrush(canvas.BrushType.SOLID_COLOR, [thisArr[0], thisArr[1], thisArr[2]]);
canvas.fillPath(myBrush);
canvas.closePath();
xPos += width;
}
};
// This the first example showing a gradient in illustrator
// drawGradientInAI(makeRGBGradientArray(color_1, color_2, 20));
// This the first example showing a dialog with a the gradient drawm
// var w = new Window("dialog", "Test");
// var p = w.add("panel");
// p.size = [200, 200];
// p.onDraw = function() {
// drawGradientInScriptUI(makeRGBGradientArray(color_1, color_2, 20), this);
// };
// w.show();
var spacing = 8;
var margins = [0,10,0,0];
// This the second example, showing a dialog the gradient and interactive sliders
var w = new Window("dialog", "Gradient Dialog");
var p = w.add("panel");
p.size = [200, 50];
// p.orientation = "row";
// p.alignChildren = ["left","center"];
p.spacing = spacing;
p.margins = margins;
p.alignment = ["fill","top"];
p.onDraw = function() {
drawGradientInScriptUI(makeRGBGradientArray(color_1, color_2, 20), this);
};
// Group sldiers 1 and 2
var g_sliders = w.add("group");
g_sliders.orientation = "row";
// g_sliders.alignChildren = ["left","center"];
g_sliders.alignment = ["fill","top"];
// Group sliders 1
var g_sliders_1 = g_sliders.add("group");
g_sliders_1.orientation = "column";
g_sliders_1.alignChildren = ["left","center"];
g_sliders_1.spacing = spacing;
g_sliders_1.margins = margins;
g_sliders_1.alignment = ["fill","top"];
var colOneLabel = g_sliders_1.add("statictext", undefined, undefined, {name: "colOneLabel"});
colOneLabel.alignment = ["fill","top"];
colOneLabel.text = " Color 1";
// Group sliders 2
var g_sliders_2 = g_sliders.add("group");
g_sliders_2.orientation = "column";
g_sliders_2.alignChildren = ["left","center"];
g_sliders_2.spacing = spacing;
g_sliders_2.margins = margins;
g_sliders_2.alignment = ["fill","top"];
var colTwoLabel = g_sliders_2.add("statictext", undefined, undefined, {name: "colTwoLabel"});
colTwoLabel.alignment = ["fill","top"];
colTwoLabel.text = " Color 2";
// Sliders color_1
var slider_1_rGrp = g_sliders_1.add("group");
slider_1_rGrp.orientation = "row";
slider_1_rGrp.alignment = ["fill","top"];
var colOneRlabel = slider_1_rGrp.add("statictext", undefined, undefined, {name: "colOneRlabel"});
colOneRlabel.text = "R";
var slider_1_r = slider_1_rGrp.add("slider");
slider_1_r.minvalue = 0;
slider_1_r.maxvalue = 255;
slider_1_r.value = color_1[0];
var slider_1_gGrp = g_sliders_1.add("group");
slider_1_gGrp.orientation = "row";
slider_1_gGrp.alignment = ["fill","top"];
var colOneGlabel = slider_1_gGrp.add("statictext", undefined, undefined, {name: "colOneRlabel"});
colOneGlabel.text = "G";
var slider_1_g = slider_1_gGrp.add("slider");
slider_1_g.minvalue = 0;
slider_1_g.maxvalue = 255;
slider_1_g.value = color_1[1];
var slider_1_bGrp = g_sliders_1.add("group");
slider_1_bGrp.orientation = "row";
slider_1_bGrp.alignment = ["fill","top"];
var colOneBlabel = slider_1_bGrp.add("statictext", undefined, undefined, {name: "colOneRlabel"});
colOneBlabel.text = "B";
var slider_1_b = slider_1_bGrp.add("slider");
slider_1_b.minvalue = 0;
slider_1_b.maxvalue = 255;
slider_1_g.value = color_1[2];
// Sliders color_2
var slider_2_rGrp = g_sliders_2.add("group");
slider_2_rGrp.orientation = "row";
slider_2_rGrp.alignment = ["fill","top"];
var colOneRlabel = slider_2_rGrp.add("statictext", undefined, undefined, {name: "colOneRlabel"});
colOneRlabel.text = "R";
var slider_2_r = slider_2_rGrp.add("slider");
slider_2_r.minvalue = 0;
slider_2_r.maxvalue = 255;
slider_2_r.value = color_2[0];
var slider_2_gGrp = g_sliders_2.add("group");
slider_2_gGrp.orientation = "row";
slider_2_gGrp.alignment = ["fill","top"];
var colOneRlabel = slider_2_gGrp.add("statictext", undefined, undefined, {name: "colOneRlabel"});
colOneRlabel.text = "G";
var slider_2_g = slider_2_gGrp.add("slider");
slider_2_g.minvalue = 0;
slider_2_g.maxvalue = 255;
slider_2_g.value = color_2[1];
var slider_2_bGrp = g_sliders_2.add("group");
slider_2_bGrp.orientation = "row";
slider_2_bGrp.alignment = ["fill","top"];
var colOneRlabel = slider_2_bGrp.add("statictext", undefined, undefined, {name: "colOneRlabel"});
colOneRlabel.text = "B";
var slider_2_b = slider_2_bGrp.add("slider");
slider_2_b.minvalue = 0;
slider_2_b.maxvalue = 255;
slider_2_b.value = color_2[2];
// Interactive sliders
slider_1_r.onChanging = slider_1_g.onChanging = slider_1_b.onChanging = slider_2_r.onChanging = slider_2_g.onChanging = slider_2_b.onChanging = function() {
color_1 = [slider_1_r.value, slider_1_g.value, slider_1_b.value];
color_2 = [slider_2_r.value, slider_2_g.value, slider_2_b.value];
p.hide();
p.show();
};
w.show();
};
callDialog();
Copy link to clipboard
Copied
@oneDegree @Silly-V @CarlosCanto
I have working code for the color picker in Photoshop, it took me some time to get it to work with Illustrator. Quite baffled they dont have the same code usage for stuff like forground color and background color. As well as for calling the color picker.
For now it work in illustrator, i had the code working for Photoshop already. I check if i can make this "sort" of universal for both apps.
I still need to some work, but the color picker updates the sliders and also updates the gradient. The sldiers dont update the color picker preview color yet. But that wont be much work... 😉
here's a preview, i used dropbox to much hustle to get it on youtube
Copy link to clipboard
Copied
This is absolutely amazing, and exactly what I had in mind - appreciate your work on this tremendously!
Will play with this, and share with the original script creator.
Again, thanks!
Copy link to clipboard
Copied
This script also seems to have gotten broken due to this community update. I dont see anything drawn in the panel. I need to figure out where to place the [i] and see why it wont draw anything.
My first check was to see if declared variables get through into the functions. I noticed that p.onDraw function should draw the color rects. But when i add an alert inside the function which tells me what color_1 is, i dont get anything in return.