Scripting in Illustrator

Basic notions for Javascript scripting in Illustrator

This documentation has been written with Adobe Illustrator 2020 for macOS. Some paths and commands might differ in Adobe Illustrator for Windows and later versions of Adobe Illustrator.

In our practice, Illustrator is mainly used with drawings that were previously made using Rhino. We consider that drawing commands such as Polyline, Trim, Hatch are more powerful in Rhino, and therefore we usually compose our 2D drawings firstly in Rhino.

However, when it comes to colors, line weights, and plot styles in general, Illustrator gives a much more direct feedback of what the drawing will look like.

When there are a lot of drawings following the same logic, applying styles in Illustrator may become a repetitive and time consuming task. This is the reason we started developing scripts to automate these tasks in Illustrator.

For a complete documentation about scripting in Illustrator, check the official documentation here.

Writing a simple script to transform Illustrator elements

Illustrator reads several kind of scripts: AppleScript, Javascript and VBScript. In this documentation, we'll use Javascript.

Notions in Javascript can be helpful to follow this tutorial. If you don't know anything about Javascript, it might help to follow a tutorial about Javascript basics.

To create a script file, we need to use a text editor, like Sublime Text or VSCode. In this tutorial, we'll be using Sublime Text.

We will create a file called script.js, and open it.

The first thing we'll have to declare in this file is the document: we are going to create a variable called doc to which we will refer to call elements that are in it (layers, paths).

let doc = app.activeDocument;

Let's say we want to select all elements from a layer called black-lines and we want to do the following:

  • make the lines continuous

  • apply a RGB color (0, 0, 0)

  • apply a line weight (0.5 pt)

  • make sure that they have no fill color

In order to select all elements from the black-lines layer, we will write the following.

let lines = doc.layers['black-lines'].pathItems;

Now, all pathItems (Illustrator terminology to designate drawn elements) from this layer are stored in the lines variable.

All we have to do is to iterate through all these elements and apply the transformations mentioned earlier. To achieve this, we will use a for loop.

for (i = 0; i < lines.length; i++) {
    lines[i].strokeDashes = [];
    lines[i].strokeColor = makeColor(0, 0, 0);
    lines[i].strokeWidth = 0.5;
    lines[i].filled = false;
};

However, this script will not work, since we are calling a function named makeColor on line 3, and we haven't declared it yet.

Colors have to be declared as Javascript objects, so we will make a function to make it easier.

function makeColor(r, g, b){
    let color = new RGBColor();
    color.red = r;
    color.green = g;
    color.blue = b;
    return color;
};

This example gives us the ability to create RGB colors.

To create CMYK colors, the following function can be used.

function makeCMYKColor(c, m, y, k){
    let color = new cmykColor();
    color.cyan = c;
    color.magenta = m;
    color.yellow = y;
    color.black = k;
    return color;
};

With these few simple steps, we get the following code which completes our specifications (make the lines continuous, apply a RGB color, set the line weight, make sure there is no fill color).

// declaring the document
let doc = app.activeDocument;

// creating the makeColor function in order to easily handle colors
function makeColor(r, g, b){
    var color = new RGBColor();
    color.red = r;
    color.green = g;
    color.blue = b;
    return color;
};

// creating the lines variable and adding the elements form the 'black-lines' layers in it.
let lines = doc.layers['black-lines'].pathItems;

// applying transformations to each element contained in the lines variable
for (i = 0; i < lines.length; i++) {
    lines[i].strokeDashes = [];
    lines[i].strokeColor = makeColor(0, 0, 0);
    lines[i].strokeWidth = 0.5;
    lines[i].filled = false;
};

When you are done writing this script in your text editor, save your script.js file and load it in Illustrator by doing File > Scripts > Other script.

Playing with the parameters

As we saw above, we can apply several transformations to the Illustrator elements. We will review them one by one.

Line type

The first parameter we applied is called strokeDashes, and controls the line type. It can be continuous, or customized to match whatever kind of line you want to draw.

In order to control this parameter, we have to give it an array. In the example above, we set up an empty array [], which makes the line continuous.

The following values will make a dotted line, a dashed line, or a dash-dot line.

const continuous = [];
const dots = [0, 1];
const dashed = [2, 3];
const dashdot = [2, 2, 0, 2];

It is a good practice to declare these values at the top of the code, in order to use them later. We declared them as constants, because those values are not supposed to change.

With these values declared as constants, it is possible to call them by their name in the code.

// previously we made a continuous line with this following line of code
lines[i].strokeDashes = [];

// with values declared beforehand, we can write the following
lines[i].strokeDashes = continuous;

Fill color and patterns

It is possible to add a fill color or a fill pattern to a shape. To add a fill color, we'll use a line from the code previously explained, and firstly turn false into true. Then we just need to add a new parameter to det up the color.

lines[i].filled = true;
lines[i].fillColor = makeColor(0, 0, 0);

In this example, we're using the makeColor function again, but it is also possible to use a pattern defined in Illustrator.

Patterns have names: when you double click on a pattern, you can see and modify these names. Names are important to call these patterns from our script. Let's say that we are using a pattern called "Feuillage". The following line of code is an example of how you can call this pattern in your script and use it as a fill color.

lines[i].fillColor = doc.swatches['Feuillage'].color;

As we saw earlier, we are using the doc variable, that contains all informations about our current drawing. Calling swatches on the doc object gives us the ability to choose a pattern by its name.

Using try...catch to sequence transformations

In our workflow, we prepared scripts that contain transformations for all the layers we use in Rhino. However, the drawings we export from Rhino are not always using all the layers. This results in an exported Illustrator file that contains only the layers that contains drawn elements.

For example, our script is prepared to make transformations on Layer-1, Layer-2, and Layer-3, but our Illustrator file only contains Layer-1 and Layer-2.

With the code explained above, the script would throw an error, because it would look for Layer-3 and would not find it.

To keep a script that works easily for all files, we put our code in try...catch blocks. If the layer does not exist, the script simply goes to the next block of code, without interrupting or throwing an error.

try {
  lines = doc.layers['black-lines'].pathItems;
  for (i = 0; i < lines.length; i++) {
    lines[i].strokeDashes = [];
    lines[i].strokeColor = makeColor(0,0,0);
    lines[i].strokeWidth = 0.4;
    lines[i].filled = false;
  }
} catch (e) {};

One drawback about this method is that it won't throw any error if something fails. To test your code, you can add an alert in the catch block, in order to display errors and debug your code.

try {
  // your code here
} catch (e) {
  alert(e);
};

Last updated