# Scripting Illustrator - Convert A Flat Process Color Into A Matching Gradient

We all are quite familiar with Adobe Illustrator and its User Interface. In our daily creative tasks we use a lot of features, such as: menu, pallets, colors, plug-ins and tools. We use these features in the form of a UI. These UI features are brought forward to us through various scripts and plug-ins.

In a simpler way, we can code scripts to automate tasks or to obtain some effect in Illustrator. Follow along to learn how to do that. In this tutorial, we will code in Javascript a script that will convert a flat process filled object into its matching gradient.

### Vector Plus

Want access to the full Vector Source files and downloadable copies of every tutorial, including this one? Join Vector Plus for just 9\$ a month.

### Tutorial Details

• Program: Adobe Illustrator CS3 and ExtendedScript Toolkit
• Difficulty: Intermediate
• Estimated Completion Time: 3 to 4 Hours

### AIM of the Script

We want this script to perform a very simple task. In Adobe Illustrator, when a user selects some objects filled with a Flat CMYK Color, and executes this Script; the objects shall get converted into a matching CMYK Gradient fill. The output gradient will be somewhat similar to a gradient overlay effect seen in multiply mode. This is shown in the image below.

Hence, the aim of our script is to convert a flat CMYK filled object into a dark-to-light matching gradient. This is a simple action that is a good exercise to learn how to script for Illustrator.

### Logic and Algorithm

The logic for converting a flat color into a dark-to-light gradient can be understood in five easy steps:

• Step 1: Pick the color of the current object. i.e. currentColor = color of currently selected object.
• Step 2: Create a new gradient color with two rampstops: startColor and endColor.
• Step 3: startColor = currentColor – gShift i.e. lighten the original color.
• Step 4: endColor = currentColor + gShift i.e. darken the original color.
• Step 5: Apply the new gradient with startColor and endColor to the object.

Where, gShift is the amount of gradient shift that will be entered by the user. The above algorithm can be easily understood from the pictorial representation shown below.

Apart from the core logic, we will implement some validations and checks for proper functioning of this script. These validations will be covered at various stages of this tutorial. Before heading towards the actual tutorial, let's get familiar with some prerequisites.

### Introduction to Scripting

This tutorial requires some basic knowledge of scripting and its environment. To get familiar with Illustrator's Scripting Environment, you can have a quick look into the documentation available in your Illustrator's installation folder go to installation_Directory \ Adobe \ Adobe Illustrator CS3 \ Scripting \ Documentation. Here, you will find the following documents to get started with JavaScript:

• Illustrator CS3 Scripting Guide.pdf
• Illustrator CS3 JavaScript Reference.pdf
• JavaScript Tools Guide CS3.pdf

### Types of Scripts

There are three types of scripts we can write for Illustrator. These are: AppleScript, JavaScript and VBScript. Since JavaScript is supported on both Windows and Mac OS, we will code our logic in JavaScript. The syntax and notations are very similar to the standard JavaScript. The only difference is about the extension. For Illustrator, we will denote all the JavaScript files with an extension .jsx instead of the common .js extension.

### Required Tools

Although, you can code the entire JavaScript in any of your favorite text editor; it is advisable to use the Adobe ExtendedScript Toolkit. By using this application, we can run, debug, test and check our code synchronously with Illustrator.

Note: Throughout this tutorial, we will denote ExtendedScript Toolkit with a short form - ESTK.

### Step 1

Open Adobe ExtendedScript Toolkit and create a New JavaScript File. Next, select Adobe Illustrator from the drop-down list for target application. This tells the ESTK that we are writing JavaScript for a particular application, i.e. Adobe Illustrator.

### Step 2 - Write a Simple Code Snippet

In the code editing area, insert the following lines of code:

In the above code, we are checking if there are any documents currently opened in Illustrator. This is done via

app.documents.length. i.e. The top level object in any Adobe Application DOM is the application object. Next is the document object, which further holds objects like colors, layers, text, pages etc. Save this file on your hard drive as "test.jsx."

### Step 2.1 - Executing the Script

There are two ways to execute the Script:

#### 1. Executing from ESTK

If you wish to run your script through ESTK, press the Play button as shown below.

This will automatically launch the Adobe Illustrator application and will generate the alert message. You can halt or stop the execution by pressing the pause or stop buttons respectively.

#### 2. Executing from Illustrator

To execute this script from Illustrator, go to File > Scripts > Other Script (Command + F12) and locate your newly created file "test.jsx." After you click Open, the script will get executed.

So what did you see? An alert message, "No documents available."

Next, create a couple of new documents in Illustrator and run this script again. This time, you will see an alert, "Documents are available."

Up to this point, we have written and tested a small piece of code. This was done as a warm-up exercise to get familiar with ESTK and Illustrator. In our next steps, we are going to work on the actual script.

### Step 3 - The Code Structure

Return back to ESTK and delete the testing code that we created in Step 2. Next, add the following lines of code into "test.jsx:"

In the above code structure, we are simply creating a pre-requisite check for our main logical function – converToGrad(). i.e. The main logic should execute only if the following conditions are met:

1. At least one document with one object exists, so that we can work on it.
2. The document color space should be CMYK, because the entire logic is based upon CMYK colors.

### Step 3.1 - Understanding the DOM Entities

app.documents.length returns the total number of documents opened in Illustrator.

An activeDocument object refers to the current (active) document in which you are working.

pathItems refers to a collection of all the pathItem objects within an Illustrator document.Any graphical item like rectangle, ellipse, polygon, line, custom shapes etc are denoted as pathItem; and a collection of all these pathItem are denoted as pathItems. Hence, app.activeDocument.pathItems.length will return the number of graphical entities contained in the current document.

The documentColorSpace object defines the color mode of the document. We are making this validation because all the logic in this script will be based upon CMYK color space.

The basic code structure is all set and done. Next, we will enter into convertToGrad() function.

### Step 4 - Starting with the Main Logic

The first and foremost requirement of our main logic is to fetch the total number of selected items. If no items are selected, the script shall notify you to select at least one object. For this, add the following lines of code into convertToGrad() function:

var items = selection creates a new variable items and assigns entire selection to it. In the next line, items.length returns the total number of selected items, which are assigned to totalSelected.

### Step 5 - Getting the User Data

To convert a flat color into a gradient, we will prompt the user to enter some values for Gradient Shift and the Gradient Angle. But before that, let's review what they are.

Gradient Shift: This is a numeric value which decides how much color will be added or removed from the original color. This is the core part of our logic in converting a flat color into a gradient.

How does a Gradient Shift work? To understand how it works, consider a simple example of an object filled with CMYK values: C=50, M=20, Y=100 and K=30 respectively.

Next, we ask the user to enter a value for Gradient Shift. Let's denote this value by gShift, and the user has entered 10 for gShift.

Once we've got the gShift value, we will create two gradient stops for our object. The first stop, i.e. the lighter one; will have all the CMYK values decremented by gShift. Whereas, the last stop, i.e. the darker one, will have all the CMYK values incremented by gShift.

This way, a dark to light gradient will be generated from the actual fill color. We will also perform some validations to constrain the CMYK values within 0 and 100, because adding or subtracting a gShift value can move the CMYK values beyond 0 or 100.

Gradient Angle: Although not a part of the core logic, we will use this feature to provide some accessibility and freedom to choose a custom angle for the resultant gradient. The usage of gradient angle will be seen in the later stage of this tutorial.

Let's return back to the code and fetch the user data.

### Step 6

To fetch the user data, enter the following lines of code in the if(totalSelected >0) block:

In the above lines of code, we are prompting a user to enter some value for gradient shift and gradient angle. The Math.round() function rounds the entered value into a whole number. (Note: You can skip Math.round() if you wish to have decimal values accepted.) The default values for gShift and gradAngle are set to "10" and "0.0" respectively.

Note that we are also validating the entered values for null and zero. Null is encountered when a user clicks the Cancel button. Also, we are restricting the gShift value within 0 and 100.

Once we have the gShift and gradAngle values, we can proceed ahead for the rest of the code.

### Step 7 - Working on the Selected Objects

Just after the gradAngle declaration, enter the following lines of code:

app.activeDocument.selection[j] returns the selected object one-by-one for each iteration of j.

For each selected object, we are making some validations and checks. These checks are crucial at this stage. The first check is to determine if the object is a compound item or a group item. Since this script will not work directly on groups or compound objects, this check is mandatory.

In the next level, we are checking if the selected object is already a gradient, pattern or spot color. If so, these objects will be skipped.

There is one more check for grayColor specification. GrayColor is slightly different than CMYK Color specification.

A detailed technique is involved for treating objects with grayColor specification, which I am not including at this stage of the tutorial. However, this technique is included in the source files for your interest.

### Step 8 - Pick and Split the Color

As per our logic and algorithm, we will pick the color for each selected object and split its CMYK values into four different variables, as shown below:

Note: All these lines of code shall come within "Perform color conversion" block, as shown in Step 7.

pathItem.fillColor returns the fill color of a particular path item. In our case, the pathItem is currentObject. We are using color.cyan, color.magenta, color.yellow and color.black properties to retrieve the C, M, Y and K values respectively into four different variables. Once we set these values, we can easily offset them with gShift.

### Step 9 - Declare Colors for Gradient Rampstops

Our resultant gradient will have two gradient stops. Let's denote them with startColor and endColor. The variable declaration for these two rampstop colors will be as shown below:

The CMYKColor is a CMYK color specification used for color objects. Here, the startColor and endColor are declared as new CMYK colors.

### Step 10 - Offsetting the startColor and endColor

At this stage, we have all the necessary resources to create a new gradient. We have currentColor (with separate CMYK values), startColor, endColor and gShift. We can now set the final color values for startColor and endColor using offset technique.

### Step 10.1 - Setting the startColor

The startColor will be the lighter part of the gradient. Hence, we will subtract gShift from C, M, Y and K values of currentColor, resulting in startColor.

This is simple, but we need to perform some checks. For example, what will happen if the currentCyan is already less than gShift? Say, currentCyan is 10 and gShift is 20. The resulting cyan value for startColor will become 10-20 = (-) 10. To overcome this issue, we will modify the above set of code into the following lines of code:

### Step 10.2 - Setting the endColor

The endColor will be the darker part of the gradient. Hence, we will add gShift to C,M,Y and K values or currentColor respectively. After simple addition, the code should look as follows:

Once again, everything looks all right. But there is one complication: What will happen if the addition of gShift results in a value greater than 100? For example, currentCyan is 95 and gShift is 20. Adding these two will result as endColor.cyan = 115; which is not acceptable. So we will compensate this with some validations.

Let's create a new variable gShiftEnd, which is equal to 100-gShift. Next, we will check if the current C, M, Y or K value is greater than gShiftEnd. If so, we will set the endColor's C,M,Y or K value to 100; else we will set endColor's C, M, Y or K value by adding gShift to the current C, M, Y or K. This can be elaborated from the example we just saw above.

We have currentCyan = 95 and gShift = 20. Therefore gShiftEnd = 100 – 20. i.e. 80. Next, currentCyan is greater than gShiftEnd; so we will set endColor.cyan to 100.

Following this principle, our code will get modified to the following:

So, up to this point, the complete code will look like this:

### Step 11 - Creating the New Gradient

Now that we have set the startColor and endColor; we can proceed with the creation of the new gradient.

### Step 11.1 - Declare the Gradient

This will add a new Linear type Gradient into the current active document.

### Step 11.2 - Setting the Properties of the Newly Created Gradient

gradientStop[0] is the first gradient stop, whereas, gradientStop[1] is the last gradient stop. If you wish to have more gradient stops, you can denote them as gradientStop[2], gradientStop[3] and so on.

rampPoint is used to set the ramp-point position of the associated gradientStop. We've set the first and last ramp-point as 0 and 100 respectively. midpoint is used to set the position of the middle point between two gradient stops. We have set this to 50. Finally, we have assigned the values of startColor and endColor to the first and last gradientStops respectively.

### Step 12 - Create a Gradient Color Object

We are almost done with color conversion and gradient formation. Next, we need to apply this newly created gradient to the currently selected object. To do that, we will create a Gradient Color Object referring to the newly created gradient.

Note: We cannot apply the newly created gradient directly as a fill Color to the object. In order to use this gradient, we will have to create a new Gradient Color object, as shown below:

### Step 13 - Apply the Gradient

Finally, we will fill the currentObject with the colorOfGradient, as shown below:

We have applied a rotation matrix to the current object. This rotation matrix makes use of the gradient angle to transform the gradient. The syntax of rotation is:

 rotate (angle [,changePositions] [,changeFillPatterns] [,changeFillGradients] [,changeStrokePattern] [,rotateAbout]) 

Here, we have set changeFillgradients to "true" and the rest to "false." This is a tricky way to rotate the gradient color at a particular angle. Thanks to John Wundes for suggesting to me this intelligent technique.

### Step 14 - The Final Script

The final script after complete coding is shown below:

### Step 15 - Execute the Script

Save the script and create a new document in Adobe Illustrator. Next, create some objects with flat CMYK colors. Select some of these objects and execute the script by following the methods as described in Step 2.1.

You will be prompted to enter the Gradient Shift. Enter any value for gShift.

Next, you will be prompted for gradient angle. Enter some value for gradAngle.

Finally, you will see the output shown below.

### Conclusion and Scope

We have learned how to write scripts to automate or generate an effect. The example shown in this tutorial was a simple demonstration of what we can perform through scripts. With this example, we've learnt how CMYK colors are represented in scripts, how they work and how objects behave in the DOM of Adobe Illustrator. In our next part, we will cover a Script that melts the available gradient color into a flat CMYK color. Hope you enjoyed this introductory tutorial to scripts.

Subscribe to the Vectortuts+ RSS Feed to stay up to date with the latest vector tutorials and articles.