Advertisement
Javascript

Writing a Flexible Grid Script for Photoshop

by

Being a capable web designer means having a solid grasp on grids, especially if you want to pursue responsive web design. In this tutorial we'll take a look at a Photoshop script for generating your own custom grids, plus we'll open the hood and look at how the script is actually made.

It's quite likely that you've already used psd files from one grid system or another. You'll probably have opened the psd, complete with all its guides, then you'll have altered the document size to give yourself a bit of breathing room.

In the case of our script, it will generate Photoshop guides irrespective of the document size. It will allow us to specify the number of columns, the gutter size and the layout width. Okay, enough with the introductions, let's dive in.


During this tutorial we'll be writing a Photoshop scriptlet in JavaScript. Here below are the functions, methods and other details that we'll cover.

  • Use of Variables for active document reference.
  • Use of Prompt to get input from user.
  • Number() function to ensure Number data type only.
  • Guides.add() to add guides to our document.
  • User of "for" loop to repeat a process.
  • Use of "if" to conditionally execute a code or skip it.
  • How to change documents measuring units.

Before we jump into the development process, let's first quickly cover how to actually install and use the script in Adobe Photoshop.


Step 1: Usage Downloading and Installing

This script is compatible with Photoshop CS5 and above. You can download the script from the above link "Download: Source code" or you can download updated versions of the script from my website. After you have downloaded the script (the .jsx file), copy the file to [Photoshop root]\Presets\Scripts.

You'll then be able to access the script within Photoshop by going File > Scripts as shown below.


Step 2: Usage Launching the Script

Before you launch this script you'll need to have at least one active document open (currently the script won't run and will throw an error). After you successfully launch the script it will show its first prompt. It will ask you to enter the width of the layout to be used for your web design.

I have used a width of 960px as default, so if you don't enter a specific value at this point it will go with 960px. You can enter any width, but it should ideally be an even number. If you enter an odd value, say 955, the calculations within the script will render fractional numbers. That means, fraction of a pixel, which isn't possible where positioning guides is concerned. Even if we were to round off that fractional value, we wouldn't have 100% accurate positions for the guides.


Step 3: Usage Number of Columns

After you hit "Enter" at the first prompt (or press OK after setting the layout width) the next prompt appears which asks you to enter the number of columns you want to use in your layout. As default I am using 12 columns.


Step 4: Usage Margins and Gutter

Finally, a third prompt appears which requires value for margins (the space between boundaries and and outer columns). This value is then doubled to get the gutter space, as tends to be the case in 960 grid systems.


Step 5: Usage The Result

After you have supplied values in all three prompts you will see guides in your document arranged in the form of columns. If you don't see any guides there, you've probably turned off the visibility for guides. You can restore their visibility by going View > Show > Guides (Ctrl+;).

In the above image you can see columns, margins and gutter space. These colors are just to illustrate what is what. Red colors shows columns; white for gutter and green for margins. In actual fact you don't get these colors; simply guides as in the following image.


Now we're familiar with how to use this script, let's see how we can actually write it with JavaScript!


Step 1: Development Checking for Document

Before we actually start scripting, we need to know whether there's a Photoshop document opened and active in the application. We check it using this condition:

 if ( app.documents.length != 0 ) 
 { 
 
 //Our entire code will go here 
 
 } else { 
 
 //No active document exists
 
 }

We shall put all the following code within these first curly braces and we shall end our script with the } brace as above.


Step 2: Development Converting Units

Our first task will be to convert the measurement units of the Photoshop document to pixels - we need to be pixel perfect while designing for the web!

//This shall set  measuring units of document to Pixels.
  preferences.rulerUnits  = Units.PIXELS;

Step 3: Development Document Width

Next we'll determine the dimensions of the Photoshop document.

var doc = app.activeDocument; //save reference of active document to variable "doc" for easy typing later on
  var docWidth = doc.width; //gets the width of the document
and stores it in "docWidth"

This grid system is independent of the height of the document, we therefore don't need to retrieve it.


Step 4: Development The Horizontal Center

Now we need to find the horizontal center of the document, or document width. How do we do this? Simple; divide the document width by two.

var docXcenter = docWidth / 2 ;

At this point it may not be clear why I'm evaluating this center, but as we move on I'll describe its use within our script.


Step 5: Development User Measurements

At this point we need to ask the user about the layout width they want to use, the number of columns and gutter spacing.

For example, 960gs uses the following fixed combinations:

  • Layout width : 960px
  • 1st combination: 12 columns : 10px outer margin : 20px inner gutter
  • 2nd combination: 16 columns : 10px outer margin : 20px inner gutter
  • 3rd combination: 24 columns : 5px outer margin : 10px inner gutter

We'll achieve clearer results if we use one of these combinations (let's say the first) as a default.

// Get layout width from user. Default  to 960px.
var layoutWidth = Number ( prompt ( 'Enter layout width:' , 960 ) ) ;
 // This gets number of columns from user. Most appropriately 12,16, or 24. Default 12 columns. 
  var cols = Number ( prompt ( 'Enter numbers of columns:' , 12 ) );
// Gets margins from left right from user. Which will  later be doubled to get gutter. Default 10px
  var margin = Number ( prompt ( 'Enter space between columns:' , 10 ) );

What Exactly is Prompt()?

Okay, before we move any further, let's first take a look at what exactly "prompt" is.

prompt ("Message to user here", "Default value here");

Prompt shows a dialogue to the user with a message and an input box like below:

The user enters the required input, at which point prompt returns that input.

The first part of prompt (which appears before the comma) puts a message in a dialogue for the user. We can guide users about the input type, and valid values etc. For example;

prompt("Enter number of columns. Appropriate values are 12, 16, 24.", 12);

The second part of prompt is the default value for the prompt dialogue. In the case of columns here, we are using 12 as a default value.

And What About Number( )?

Number is a method which extracts numbers from the given input. If user has entered something other than a number (like a name or another string), the method would return a NaN (Not a Number). This sanitation makes sure that you only get the number data-type that is essential in certain situations where only numbers work.


Let's now go over the code snippet we prepared previously.

The first line gets the value of the layout width. The real matter of the website will lie within that width. As we are using 960gs the default value for this is 960px, but you can change it to whatever width you like.

In the second line, we get the number of columns our user wants to have in his layout design. 960gs uses 12, 16 or 24 columns as they work very effectively, but they're by no means compulsory.

In third line we obtain the space that lies among the columns and on the boundaries of layout. This space usually doubles among the columns as gutter.


Step 6: Development Calculating Gutter and Center

var gutter = space * 2; 
//Calculates the horizontal center of the layout and so the center of document 
  var layoutHalf = layoutWidth / 2 ;

Here, the gutter space is being calculated and assigned to the variable gutter. In the second line, we are calculating half of the layout width that we get through user input. In other words, the horizontal center of our layout.


Step 7: Development Defining Limits

In the first two lines in this section of code we're calculating the position of the left and right boundaries of our layout. We refer to these as outer limits; the left limit is minLimitOuter and the right limit is maxLimitOuter.

In the following two lines we're calculating the inner boundaries of our layout. This is effectively our layout width minus the gutter width. Think of it as being the margin that lies directly inside the layout width.

  //outer limits that is the layout width;
  var maxLimitOuter = docXcenter + layoutHalf;
var minLimitOuter = docXcenter - layoutHalf;

  //Inner limits for 960gs
  var minLimitInner = minLimitOuter + space;
  var maxLimitInner = maxLimitOuter - space;

Here comes the definition of docXcenter which we talked about earlier. docXcenter is center of our whole document width. We need to evaluate that in order to place things around the center of document. We won't place a guide in the center, but we need it to position other elements.

So what is layoutHalf? This is half of the width of the layout as defined by the user. We divided that width into halves so that we can put each half on either side of docXcenter. From here we can determine the position of the guides on the left and right edges of the layout.

The left guide's position would be (Center of document - half of layout width) and hence the guide at right edge would be (Center of document + half of layout width).


Step 8: Development Column Width

Here we calculate the width of each column. We'll need this value later when repeating the "adding guide" process.

 var colWidth = ( layoutWidth - ( cols * gutter ) ) / cols;

Step 9: Development Adding Guides to Outer Limits

Finally, we come to our first actual "guide adding" step! Here we add two guides at the layout boundaries; our outer limits.

doc.guides.add ( Direction.VERTICAL , minLimitOuter );
doc.guides.add ( Direction.VERTICAL , maxLimitOuter );

The first line adds a vertical guide to our document at the positions of minLimitOuter, the left edge of layout and maxLimitOuter the right edge of layout.

Let me explain a little more about above lines of code.

 doc.guides.add(Direction.VERTICAL/HORIZONTAL, position)

This line actually adds guides to our Photoshop document. "doc" is simply the reference to our currently active document. "guides" is an object of class guides, which lies within the document and is responsible for the behavior and properties of guides within a Photoshop document. "add" is a method of class guides which adds guides to our document.

doc.guides.add() is a method which requires only two parameters. The first is the direction of the guide, which may be vertical or horizontal. The second parameter is simply the position of the guide. If you set your units to pixels it will assume the value passed to the 2nd parameter is pixels, or any other respectively.


Step 10: Development First Loop

The first loop will deal with our first group of guides and inner limits:

  for ( i = 0 ; i < cols ; i++ ) {
  guidPos = minLimitInner + ( ( colWidth + gutter ) * i );
  if ( guidPos > maxLimitInner ) {
  break;
  }
  doc.guides.add ( Direction.VERTICAL , Number ( guidPos ) );
  }

Let's look into it. We repeat (loop) our code "cols" times , as this is the number of columns our user wants to use. In this piece of code we shall also add our inner boundaries.

The first line after the "for" starting line is a variable "guidPos" for guide position. "minLimitInner" makes sure that position of our first guide starts from minLimitInner; the inner boundaries. Then we keep multiplying the colWidth and gutter with "i" that is being iterated 0 to "cols" times. In this way we add our first group of guides to the document. These guides will be at the left of every column.

Then in second line we check if the guidPos value exceeds the maxLimitInner; the right inner boundary of document. If so it breaks out of the loop. If this condition does not fall true, the loop continues until the condition is met.

The third line of code simply adds the guides to the document at guidPos position.


Step 11: Development Second Loop

Time to deal with our second group of guides.

for ( j = 0 ; j < cols ; j++ )
	{
if ( j == 0 ) 
{ multiply = 0
  }
  else
  {
  multiply = 1;
  }

temp_gutter = ( gutter * multiply ) ;
guidPos = ( minLimitOuter - space ) + ( ( colWidth + gutter ) * ( j + 1 ) );
 if ( guidPos > maxLimitInner ) 
{
  break;
  }  
doc.guides.add ( Direction.VERTICAL , Number ( guidPos ) );

With few minor differences this piece of code adds guides to right edges of our columns and to the right inner boundary.

Here is the full code:

if ( app.documents.length != 0 ) 
{ 
    preferences.rulerUnits = Units.PIXELS;
    var layoutWidth = Number ( prompt ( ' Enter layout width: ' , 960 ) );
    var cols = Number ( prompt ( ' Enter numbers of columns: ' , 12 ) );
    var space = Number ( prompt ( ' Enter space between columns: ' , 10 ) );
    
    var doc = app.activeDocument;
    var docWidth = doc.width;
    var docXcenter = docWidth / 2;
    
    
    var gutter = space * 2; //gutter space
    var layoutHalf = layoutWidth / 2;
    
    
    //outer limits that is the layout width;
    var maxLimitOuter = docXcenter + layoutHalf;
    var minLimitOuter = docXcenter - layoutHalf;
    
    
    //Inner limits for 960gs
    var minLimitInner = minLimitOuter + space;
    var maxLimitInner = maxLimitOuter - space;
    
    var colWidth = ( layoutWidth - ( cols * gutter ) ) / cols;
    
    
    doc.guides.add ( Direction.VERTICAL , minLimitOuter );
    doc.guides.add ( Direction.VERTICAL , maxLimitOuter );
    
    
    for ( i = 0 ; i < cols ; i++ )    
    {    
        guidPos = minLimitInner + ( ( colWidth + gutter ) * i );
        
        if ( guidPos > maxLimitInner )
        { 
            break;
        }
        
        doc.guides.add ( Direction.VERTICAL , Number ( guidPos ) );
    
    }
    
    
    
    for ( j = 0 ; j < cols ; j++ ) 
    {
        if ( j== 0 )
        {
            multiply = 0
        }
        
        else
        {
            multiply = 1;
        }
        
        temp_gutter = ( gutter * multiply );
        
        guidPos = ( minLimitOuter - space ) + ( ( colWidth + gutter ) * ( j + 1 ) );
        
        if ( guidPos > maxLimitInner ) 
        {
            break;
        }
        doc.guides.add ( Direction.VERTICAL , Number ( guidPos ) );
    }
     
    }// end-if app.documents.length
        
    else
    {
       alert ( " No active document exists " );
      }

Although this script may contain flaws and drawbacks, the goal was to teach you a little about JavaScript for Photoshop within a practical example. You may not have grasped it at all, but I hope it's at least tickled your curiosity. If you have any questions at all, please feel free to leave them in the comments.

Related Posts