×

Color

The creation, blending, and application of colors to shapes and text is a common task performed in all Omni applications. This page details how to work with color values in various color spaces.

Color Functions

The following functions are used to create instances of the Color class:

Here’s an OmniGraffle script example that creates a green circle (in the RGB color space) with a 50% transparency (alpha value) overlaid on a blue square:

green-circle-blue-square
omnigraffle:///omnijs-run?script=cnvs%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0Asquare%20%3D%20cnvs%2EaddShape%28%27Rectangle%27%2Cnew%20Rect%2872%2C72%2C200%2C200%29%29%0Asquare%2EfillColor%20%3D%20Color%2ERGB%280%2C%200%2C%201%2C%201%29%0Acircle%20%3D%20cnvs%2EaddShape%28%27Circle%27%2Cnew%20Rect%28150%2C150%2C200%2C200%29%29%0Acircle%2EfillColor%20%3D%20Color%2ERGB%280%2C%201%2C%200%2C%200%2E5%29
Create Shapes with Color Fills
 

var cnvs = document.windows[0].selection.canvas var square = cnvs.addShape('Rectangle', new Rect(72,72,200,200)) square.fillColor = Color.RGB(0, 0, 1, 1) var circle = cnvs.addShape('Circle', new Rect(150,150,200,200)) circle.fillColor = Color.RGB(0, 1, 0, 0.5)

Here’s an OmniGraffle script example that adds grayscale tint swatches, from black to white in increments of 10%, to the current canvas:

omnigraffle:///omnijs-run?script=cnvs%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0AobjSize%20%3D%2048%0Aoffset%20%3D%200%0Aswatches%20%3D%20new%20Array%28%29%0Afor%28i%20%3D%200%3B%20i%20%3C%2011%3B%20i%2B%2B%29%7B%0A%09offset%20%3D%20offset%20%20%2B%20objSize%0A%09aRect%20%3D%20new%20Rect%28offset%2C%20objSize%2C%20objSize%2C%20objSize%29%0A%09graphic%20%3D%20cnvs%2EaddShape%28%27Rectangle%27%2C%20aRect%29%0A%09color%20%3D%20Color%2EWhite%28i*%2E1%2C1%29%0A%09graphic%2EfillColor%20%3D%20color%0A%09swatches%2Epush%28graphic%29%0A%7D%0AswatchStrip%20%3D%20new%20Group%28swatches%29
grayscale-swatches
Grayscale Bar - 10% Increments
 

var cnvs = document.windows[0].selection.canvas var objSize = 48 var offset = 0 var swatches = new Array() for(i = 0; i < 11; i++){ offset = offset + objSize var aRect = new Rect(offset, objSize, objSize, objSize) var graphic = cnvs.addShape('Rectangle', aRect) var color = Color.White(i*.1,1) graphic.fillColor = color swatches.push(graphic) } var swatchStrip = new Group(swatches)

Color Class Properties

Some common colors can be represented with the following property values instead of using one of the Color methods.

Common Color Values


graphic.fillColor = Color.blue

Color Instance Properties

Once a Color object has been created, you can use the following instance properties to gather information about the color object.

Color Instance Functions

Color objects can be blended to create new colors, using the blend() method:

omnigraffle://localhost/omnijs-run?script=try%7Bvar%20cnvs%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0Avar%20graphic%20%3D%20cnvs%2EaddShape%28%27Circle%27%2C%20new%20Rect%280%2C%200%2C%20200%2C%20200%29%29%0Avar%20colorA%20%3D%20Color%2Ered%0Avar%20colorB%20%3D%20Color%2Eyellow%0Avar%20blendColor%20%3D%20colorA%2Eblend%28colorB%2C%200%2E5%29%0Agraphic%2EfillColor%20%3D%20blendColor%7Dcatch%28err%29%7Bconsole%2Elog%28err%29%7D

Here’s an example of blending colors: creating an orange circle by blending red and yellow

New Shape with Blended Colors
 

var cnvs = document.windows[0].selection.canvas var graphic = cnvs.addShape('Circle', new Rect(0, 0, 200, 200)) var colorA = Color.red var colorB = Color.yellow var blendColor = colorA.blend(colorB, 0.5) graphic.fillColor = blendColor
 

ColorSpace

A color space is a specific organization of colors.

Examples

Here are some script examples using the Color class:

Hex Color Value for Color Object


function componentToHex(c){ var hex = c.toString(16); return hex.length == 1 ? "0" + hex : hex; } function HEXforColor(clrObj){ rv = clrObj.red gv = clrObj.green bv = clrObj.blue r = Math.round(rv * 255) g = Math.round(gv * 255) b = Math.round(bv * 255) colorHEX = "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); return colorHEX.toUpperCase() }
Calling the Functions


var clrObj = Color.RGB(0.22574300483333884, 0.7168752888153417, 0.996078431372549, 1) HEXforColor(clrObj) //--> "#3ab7fe"
Do Colors Match?


function RGBMatch(colorA, colorB){ return ( colorA.red === colorB.red && colorA.green === colorB.green && colorA.blue === colorB.blue ) ? true:false }

Color Info Plug-In

An OmniGraffle plug-in for displaying the color information of the selected graphic. Color object constructor statements for each of the colors (stroke, fill, text) will be logged to the console.

color-info color-info-log
Color Info of Selected Graphic
 

/*{ "type": "action", "targets": ["omnigraffle"], "author": "Otto Automator", "identifier": "com.omni-automation.og.color-info", "version": "1.0", "description": "Present the color information for the selected graphic.", "label": "Color Info", "shortLabel": "Color Info" }*/ (() => { function componentToHex(c){ var hex = c.toString(16); return hex.length == 1 ? "0" + hex : hex; } function HEXforColor(clrObj){ rv = clrObj.red gv = clrObj.green bv = clrObj.blue r = Math.round(rv * 255) g = Math.round(gv * 255) b = Math.round(bv * 255) colorHEX = "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); return colorHEX } var action = new PlugIn.Action(function(selection, sender){ // action code var graphic = selection.graphics[0] // console.clear() if(graphic.fillColor){ var graphicFillColor = graphic.fillColor var fillColorHEX = HEXforColor(graphicFillColor).toUpperCase() var red = String(graphicFillColor.red) var green = String(graphicFillColor.green) var blue = String(graphicFillColor.blue) var alpha = String(graphicFillColor.alpha) var fillValues = "R: " + red + "\n" + "G: " + green + "\n" + "B: " + blue + "\n" + "A: " + alpha console.log(`FILL: ${fillColorHEX}`, `Color.RGB(${red}, ${green}, ${blue}, ${alpha})`) } else { var fillValues = "No Fill" var fillColorHEX = "N/A" } if(graphic.strokeColor){ var graphicStrokeColor = graphic.strokeColor var strokeColorHEX = HEXforColor(graphicStrokeColor).toUpperCase() var red = String(graphicStrokeColor.red) var green = String(graphicStrokeColor.green) var blue = String(graphicStrokeColor.blue) var alpha = String(graphicStrokeColor.alpha) var strokeValues = "R: " + red + "\n" + "G: " + green + "\n" + "B: " + blue + "\n" + "A: " + alpha console.log(`STROKE: ${strokeColorHEX}`, `Color.RGB(${red}, ${green}, ${blue}, ${alpha})`) } else { var strokeValues = "No Stroke" var strokeColorHEX = "N/A" } if(graphic instanceof Shape && graphic.textColor){ var graphicTextColor = graphic.textColor var textColorHEX = HEXforColor(graphicTextColor).toUpperCase() var red = String(graphicTextColor.red) var green = String(graphicTextColor.green) var blue = String(graphicTextColor.blue) var alpha = String(graphicTextColor.alpha) var colorValues = "R: " + red + "\n" + "G: " + green + "\n" + "B: " + blue + "\n" + "A: " + alpha console.log(`TEXT: ${textColorHEX}`, `Color.RGB(${red}, ${green}, ${blue}, ${alpha})`) } else { var colorValues = "No Color" var textColorHEX = "N/A" } var message = `FILL: ${fillColorHEX}\n` + fillValues + `\n\nSTROKE: ${strokeColorHEX}\n` + strokeValues + `\n\nTEXT: ${textColorHEX}\n` + colorValues new Alert("Graphic Colors", message).show() }); action.validate = function(selection, sender){ // validation code // One single graphic selected (not a group) if (selection.graphics.length === 1){ if (selection.graphics[0] instanceof Group){ return false } else { return true } } else { return false} }; return action; })();

Find/Change Colors

This OmniGraffle plug-in will find and replace all occurrences of a specified HEX color used in any of the selected ways (fill color, stroke color, text color) in all of graphics of the current canvas. If some graphics are already selected, they will be processed, otherwise if no graphics are selected, all graphics on the canvas will be processed.

find-change-color
Find/Replace HEX Color
 

/*{ "type": "action", "targets": ["omnigraffle"], "author": "Otto Automator", "identifier": "com.omni-automation.og.find-change-color", "version": "1.7", "description": "Will replace the indicated HEX color value for fill, stroke, and text in either the selected graphics, or if no graphics are selected, all graphics on the current canvas.", "label": "Find/Change Color", "shortLabel": "Find/Change Color" }*/ (() => { var changeCount = 0 function incrementChangeCount(){ changeCount = changeCount + 1 } function componentToHex(c){ var hex = c.toString(16); return hex.length == 1 ? "0" + hex : hex; } function HEXforColor(clrObj){ rv = clrObj.red gv = clrObj.green bv = clrObj.blue r = Math.round(rv * 255) g = Math.round(gv * 255) b = Math.round(bv * 255) colorHEX = componentToHex(r) + componentToHex(g) + componentToHex(b); return colorHEX.toUpperCase() } function hexToRGBColorObject(hexStr) { var r = 0, g = 0, b = 0; r = "0x" + hexStr[0] + hexStr[1]; g = "0x" + hexStr[2] + hexStr[3]; b = "0x" + hexStr[4] + hexStr[5]; var red = (+r / 255).toFixed(10) var green = (+g / 255).toFixed(10) var blue = (+b / 255).toFixed(10) return Color.RGB(Number(red), Number(green), Number(blue), 1) } function colorMatch(hexColor, clrObj){ var objHEXvalue = HEXforColor(clrObj) var hexValue = objHEXvalue return (hexColor === hexValue) ? true:false } function RGBMatch(colorA, colorB){ return ( colorA.red === colorB.red && colorA.green === colorB.green && colorA.blue === colorB.blue ) ? true:false } function processGroup(aGroup, shouldChangeFill, shouldChangeStroke, shouldChangeText, targetHEX, replacementColor){ processItems(aGroup.graphics, shouldChangeFill, shouldChangeStroke, shouldChangeText, targetHEX, replacementColor) } function processItems(items, shouldChangeFill, shouldChangeStroke, shouldChangeText, targetHEX, replacementColor){ items.forEach(item => { if (item instanceof Shape){ var itemName = (item.name) ? item.name : "" console.log("Shape", item.id, itemName) if(shouldChangeText && item.textColor){ if (colorMatch(targetHEX, item.textColor)){ item.textColor = replacementColor incrementChangeCount() console.log("Shape", item.id, "text changed") } } if(shouldChangeFill && item.fillColor){ if (colorMatch(targetHEX, item.fillColor)){ item.fillColor = replacementColor incrementChangeCount() console.log("Shape", item.id, "fill changed") } } if(shouldChangeStroke && item.strokeColor){ if (colorMatch(targetHEX, item.strokeColor)){ item.strokeColor = replacementColor incrementChangeCount() console.log("Shape", item.id, "stroke changed") } } } else if (item instanceof Line){ var itemName = (item.name) ? item.name : "" console.log("Line", item.id, itemName) if(shouldChangeStroke && item.strokeColor){ if (colorMatch(targetHEX, item.strokeColor)){ item.strokeColor = replacementColor incrementChangeCount() console.log("Line", item.id, "stroke changed") } } } else if (item instanceof Group){ var itemName = (item.name) ? item.name : "" console.log("Group", itemName) processGroup(item, shouldChangeFill, shouldChangeStroke, shouldChangeText, targetHEX, replacementColor) } else { var itemName = (item.name) ? item.name : "" console.log("Unknown", item.id, itemName) } }) } var action = new PlugIn.Action(function(selection, sender){ // action code var targetColorField = new Form.Field.String( "targetColor", "Search for", "FFFFFF" ) var replaceColorField = new Form.Field.String( "replaceColor", "Replace with", "000000" ) var fillCheckbox = new Form.Field.Checkbox( "shouldProcessFill", "Fill Color", false ) var strokeCheckbox = new Form.Field.Checkbox( "shouldProcessStroke", "Stroke Color", false ) var textCheckbox = new Form.Field.Checkbox( "shouldProcessText", "Text Color", false ) var inputForm = new Form() inputForm.addField(targetColorField) inputForm.addField(replaceColorField) inputForm.addField(fillCheckbox) inputForm.addField(strokeCheckbox) inputForm.addField(textCheckbox) var formPrompt = "Enter 6-character HEX colors (no #):" var buttonTitle = "Continue" var formPromise = inputForm.show(formPrompt,buttonTitle) inputForm.validate = function(formObject){ var processFill = formObject.values['shouldProcessFill'] var processStroke = formObject.values['shouldProcessStroke'] var processText = formObject.values['shouldProcessText'] var values = [processFill, processStroke, processText] var targetColor = formObject.values['targetColor'] if(!targetColor){return false} if (/^[a-f0-9]+$/i.test(targetColor)){ var targetStatus = (targetColor.length === 6) ? true:false } else {var targetStatus = false} var replaceColor = formObject.values['replaceColor'] if (!replaceColor){return false} if (/^[a-f0-9]+$/i.test(replaceColor)){ var replacetStatus = (replaceColor.length === 6) ? true:false } else {var replacetStatus = false} return (values.includes(true) && targetStatus === true && replacetStatus === true) ? true:false } formPromise.then(function(formObject){ try { console.clear() var shouldChangeFill = formObject.values['shouldProcessFill'] var shouldChangeStroke = formObject.values['shouldProcessStroke'] var shouldChangeText = formObject.values['shouldProcessText'] var targetHEX = formObject.values['targetColor'] console.log("targetHEX",targetHEX) var targetColor = hexToRGBColorObject(targetHEX) var replaceHEX = formObject.values['replaceColor'] console.log("replaceHEX",replaceHEX) var replacementColor = hexToRGBColorObject(replaceHEX) console.log("fill:" + shouldChangeFill,"stroke:" + shouldChangeStroke,"text:" + shouldChangeText) // use selected graphics or if none, all graphics var targetGraphics = selection.graphics if (targetGraphics.length === 0){ var cnvs = selection.canvas var targetGraphics = cnvs.graphics } changeCount = 0 processItems(targetGraphics, shouldChangeFill, shouldChangeStroke, shouldChangeText, targetHEX, replacementColor) console.log("// Script to locate an item by ID:") console.log("cnvs = document.windows[0].selection.canvas") console.log("graphic = cnvs.graphicWithId(*idNumber*)") console.log("document.windows[0].selection.view.select([graphic],false)") var message = String(changeCount) + " items were altered." new Alert("COMPLETED",message).show() } catch(err){console.error(err)} }) formPromise.catch(function(err){ console.error("form cancelled", err.message) }) }); action.validate = function(selection, sender){ // validation code return (selection.canvas.graphics.length > 0) }; return action; })();

Opacity

The opacity of a graphic is controlled by the alpha value of its fill or stroke color. For example, this script will generate an instance of the Color class whose color is red with 50% transparency:

Color with 50% Opacity


Color.RGB(1, 0, 0, 0.5) //--> [object Color] {alpha: 0.5, blue: 0, brightness: 1, colorSpace: [object ColorSpace: RGB], green: 0, hue: 1, red: 1, saturation: 1, white: 0.3}

Set Graphic Opacity

Here is an Omni Automation plug-in for OmniGraffle that will change the opacity of the selected items (shapes, lines, and groups) to the percentage value provided by the plug-in user:

Set Opacity of Selected Items
 

/*{ "type": "action", "targets": ["omnigraffle"], "author": "Otto Automator", "identifier": "com.omni-automation.og.set-opacity-of-selection", "version": "1.0", "description": "This action will set the opacity of the selected graphics to the indicated percentage.", "label": "Set Opacity", "shortLabel": "Opacity" }*/ (() => { function processStroke(item,opacity){ var c = item.strokeColor var newColor = Color.RGB(c.red, c.green, c.blue, opacity) item.strokeColor = newColor } function processFill(item,opacity){ var c = item.fillColor var newColor = Color.RGB(c.red, c.green, c.blue, opacity) item.fillColor = newColor } function processGroup(group,opacity,shouldIncludeStroke){ group.graphics.forEach(item => { if(item instanceof Shape){ processFill(item,opacity) if (shouldIncludeStroke){processStroke(item,opacity)} } if (item instanceof Line){ processStroke(item,opacity) } if (item instanceof Group){ processGroup(item,opacity,shouldIncludeStroke) } }) } var action = new PlugIn.Action(function(selection, sender){ // action code // selection options: canvas, document, graphics, lines, solids, view var textInputField = new Form.Field.String( "textInput", null, "50" ) var checkSwitchField = new Form.Field.Checkbox( "shouldIncludeStroke", "Apply opacity setting to shape’s stroke", true ) var inputForm = new Form() inputForm.addField(textInputField) inputForm.addField(checkSwitchField) var formPrompt = "Enter an opacity value (0-100):" var buttonTitle = "Continue" var formPromise = inputForm.show(formPrompt,buttonTitle) inputForm.validate = function(formObject){ inputText = formObject.values['textInput'] if (!inputText) {return false} var isnum = /^[0-9]+$/i.test(inputText) if (isnum){ var opacityValue = Number(inputText) return ((opacityValue >= 0 && opacityValue <= 100)? true:false) } return false } formPromise.then(function(formObject){ try { var textValue = formObject.values['textInput'] console.log('textValue: ',textValue) var shouldIncludeStroke = formObject.values['shouldIncludeStroke'] var opacityValue = Number(inputText) * .01 selection.graphics.forEach(item => { if (item instanceof Shape){ processFill(item,opacityValue) if (shouldIncludeStroke){processStroke(item,opacityValue)} } if (item instanceof Line){ processStroke(item,opacityValue) } if (item instanceof Group){ processGroup(item,opacityValue,shouldIncludeStroke) } }) } catch(err){ console.error(err.message) new Alert("ERROR",err.message).show() } }) formPromise.catch(function(err){ console.error("form cancelled", err.message) }) }); action.validate = function(selection, sender){ // validation code // selection options: canvas, document, graphics, lines, solids, view return (selection.graphics.length > 0) }; return action; })();