We are often tasked to create printed squares to closely match a PMS color. While there are many good starting points, in the end we have to produce a range of 5-6 variations. While Illustrator does offer some tricks to employ, you still have to go through and label each square with the CMYK call outs. Tedious and prone to error. Let me introduce "Swatch-nado". Make and select two new swatches or select two from your existing library. Then run the script. It will create all the squares, blending between the swatches and labeling them underneath each square. Try it out. I do have a request. It fails on Global Swatches. And I can't seem to make the exact number of squares at input. It always adds 1. Anyway here it is with attribution in the script.
// modified to create blended swatches between 2 input swatches//
// create a set of swatches that blend the start color to the end color ( selected swatches )
//modified by roy solorio
var document = app.activeDocument
document.defaultStroked = false;
function createBlendSwatches( steps ){
var doc = activeDocument,
swatches = doc.swatches,
swatchGroups = doc.swatchGroups,
startSwatch = swatches.getSelected()[0],
endSwatch = swatches.getSelected()[1],
steps = Math.floor( steps );
if( steps < 1 ){
alert( "steps must be 1 or greater" )
return;
}
if( swatches.getSelected().length != 2 ){
alert( "expected two swatches to be selected found:" + swatches.getSelected().length );
return;
} else {
var sGrp = swatchGroups.add();
with( sGrp ){
name="colorAverageSwatchs";
}
if( startSwatch.color == "[CMYKColor]" && endSwatch.color == "[CMYKColor]" ){
//alert ( "CMYK swatches selected" );
var colorIncrement = [ (endSwatch.color.cyan - startSwatch.color.cyan)/steps , (endSwatch.color.magenta- startSwatch.color.magenta)/steps, (endSwatch.color.yellow - startSwatch.color.yellow)/steps, (endSwatch.color.black - startSwatch.color.black)/steps ];
sGrp.addSwatch( DupSwatch( startSwatch ));
for( i=1; i<steps; i++){
var myColor = new CMYKColor(),
myNewSwatch = swatches.add();
with( myColor ){
cyan = Math.round( startSwatch.color.cyan + colorIncrement[0] * i );
magenta = Math.round(startSwatch.color.magenta + colorIncrement[1] * i );
yellow = Math.round( startSwatch.color.yellow + colorIncrement[2] * i );
black = Math.round( startSwatch.color.black + colorIncrement[3] * i );
}
with( myNewSwatch ){
name = ("C="+myColor.cyan+" "+"M="+myColor.magenta+" "+"Y="+myColor.yellow+" "+"K="+myColor.black );
color = myColor;
}
sGrp.addSwatch( myNewSwatch );
}
sGrp.addSwatch( DupSwatch( endSwatch ));
//alert( "created Swatch Group:"+sGrp.name );
return( sGrp );
} else if(startSwatch.color == "[RGBColor]" && endSwatch.color == "[RGBColor]" ){
//alert ( "RGB swatches selected" );
var colorIncrement = [ (endSwatch.color.red- startSwatch.color.red)/steps , (endSwatch.color.green- startSwatch.color.green)/steps, (endSwatch.color.blue - startSwatch.color.blue)/steps ];
sGrp.addSwatch( DupSwatch( startSwatch ));
for( i=1; i<steps; i++){
var myColor = new RGBColor(),
myNewSwatch = swatches.add();
with( myColor ){
red = Math.round( startSwatch.color.red + colorIncrement[0] * i );
green = Math.round( startSwatch.color.green + colorIncrement[1] * i );
blue = Math.round( startSwatch.color.blue + colorIncrement[2] * i );
}
with( myNewSwatch ){
name = ("r"+myColor.red+","+"g"+myColor.green+","+"b"+myColor.blue );
color = myColor;
}
sGrp.addSwatch( myNewSwatch );
}
sGrp.addSwatch( DupSwatch( endSwatch ));
alert( "created swatch:"+myNewSwatch.name );
return( sGrp );
} else {
alert( "requires 2 swatches of the same type, either RGB or CMYK" );
return;
}
}
}
function DupSwatch( swatch ){
var copy = activeDocument.swatches.add();
with( copy ){
name = swatch.name;
color = swatch.color;
}
return( copy );
}
//=========
//
// MODIFIED
//
/////////////////////////////////////////////////////////////////
// Render Swatch Legend v1.1 -- CS, CS2, CS3, CS4, CS5
//>=--------------------------------------
//
// This script will generate a legend of rectangles for every swatch in the main swatches palette.
// You can configure spacing and value display by configuring the variables at the top
// of the script.
// update: v1.1 now tests color brightness and renders a white label if the color is dark.
//>=--------------------------------------
// JS code (c) copyright: John Wundes ( john@wundes.com ) www.wundes.com //
//////////////////////////////////////////////////////////////////
function RenderSwatchLegend( swatchGrp )
{
var doc = activeDocument,
swatches = swatchGrp.getAllSwatches(),
displayAs = "CMYKColor", //or "RGBColor"
rectRef=null,
textRectRef=null,
textRef=null,
rgbColor=null,
w=100;
h=100,
h_pad = 36,
v_pad = 100,
y_pad = 18,
x_pad = 94,
t_h_pad = 0,
t_v_pad = -104,
x=null,
y=null,
black = new GrayColor(),
white = new GrayColor()
sc=0
wedgeCount = 25;
cols = Math.floor(( doc.width - h_pad ) / ( w + y_pad ));
black.gray = 100;
white.gray = 0;
var wedgeLayer = doc.layers.add();
with(wedgeLayer){
name = "Swatch-nado";
locked= false;
}
{var text1 = doc.textFrames.add();
text1.translate(h_pad,-x_pad);
text1.textRange.characterAttributes.size = 18;
text1.textRange.characterAttributes.textFont = app.textFonts["Gotham-Book"];
text1.contents = "PMS xxxx";
}
var newGroup = doc.groupItems.add();
with( newGroup ){
name = "Color";
parent = wedgeLayer;
}
newGroup.move( doc, ElementPlacement.PLACEATBEGINNING );
for(var c=0,len=swatches.length;c<len;c++)
{
var swatchGroup = doc.groupItems.add();
swatchGroup.name = swatches[c].name;
if(swatchGroup.name != "[None]" && swatchGroup.name != "[Registration]")
{
x= (w+y_pad)*(sc% cols) + h_pad;
y=((h+v_pad)*(Math.floor((sc+.01)/cols))*-1) - v_pad;
rectRef = doc.pathItems.rectangle(y,x, w,h);
rgbColor = swatches[c].color;
rectRef.fillColor = rgbColor;
textRectRef = doc.pathItems.rectangle(y+t_v_pad,x+ t_h_pad,w,h+(.8*t_v_pad));
textRef = doc.textFrames.areaText(textRectRef);
textRef.contents = swatches[c].name;
textRef.textRange.characterAttributes.size = 8;
textRef.textRange.characterAttributes.textFont = app.textFonts["Gotham-Book"];
textRef.textRange.fillColor = black;
rectRef.move( swatchGroup, ElementPlacement.PLACEATBEGINNING );
textRef.move( swatchGroup, ElementPlacement.PLACEATBEGINNING );
swatchGroup.move( newGroup, ElementPlacement.PLACEATEND );
sc ++;
}
}
}
function rgb2cmyk (r,g,b) {
var computedC = 0;
var computedM = 0;
var computedY = 0;
var computedK = 0;
//remove spaces from input RGB values, convert to int
var r = parseInt( (''+r).replace(/\s/g,''),10 );
var g = parseInt( (''+g).replace(/\s/g,''),10 );
var b = parseInt( (''+b).replace(/\s/g,''),10 );
if ( r==null || g==null || b==null ||
isNaN(r) || isNaN(g)|| isNaN(b) )
{
alert ('Please enter numeric RGB values!');
return;
}
if (r<0 || g<0 || b<0 || r>255 || g>255 || b>255) {
alert ('RGB values must be in the range 0 to 255.');
return;
}
// BLACK
if (r==0 && g==0 && b==0) {
computedK = 1;
return [0,0,0,1];
}
computedC = 1 - (r/255);
computedM = 1 - (g/255);
computedY = 1 - (b/255);
var minCMY = Math.min(computedC,
Math.min(computedM,computedY));
computedC = (computedC - minCMY) / (1 - minCMY) ;
computedM = (computedM - minCMY) / (1 - minCMY) ;
computedY = (computedY - minCMY) / (1 - minCMY) ;
computedK = minCMY;
return [Math.floor(computedC*100),Math.floor(computedM*100),Math.floor(computedY*100),Math.floor(computedK*100)];
}
function is_dark(color){
if(color.typename)
{
switch(color.typename)
{
case "CMYKColor":
return (color.black>50 || (color.cyan>50 && color.magenta>50)) ? true : false;
case "RGBColor":
return (color.red<100 && color.green<100 ) ? true : false;
case "GrayColor":
return color.gray > 50 ? true : false;
case "SpotColor":
return is_dark(color.spot.color);
return false;
}
}
}
function main(){
var userSteps = Number( prompt( "After the FIRST SWATCH, how many more do you need?", 5 ));
var swatchGrp = createBlendSwatches( userSteps );
RenderSwatchLegend( swatchGrp );
}
main();