I'm trying to create a JavaScript function that can be added to a button in a PDF (that has been created in Adobe inDesign) that changes the colour of all shapes to that of a hex colour code entered into a text box. For example, if the user entered 'FFFFFF' into the text box then clicked this button, it would change all the shapes to white.
The next requirement is for any text placed on top of any shapes that have had their colour changed, to have their colour changed to contrast the new colour and still be legible (white text on dark colour shapes, black text on light colour shapes).
The final addition is for any text that includes the marker '[color]' to have it's fill colour changed to that of the hex code entered. When designing this document in InDesign, I would use a GREP style to make any instance of the '[color]' marker have a text size of 0.1pt and have no fill colour, so the user wouldn't have to see the markers on the final PDF. Although, if there are any methods of achieving the same results within this function, it would be gratefully received.
This is the code I have so far:
function changeColor() {
// Get the user-entered hexadecimal color value
var hexValue = getField("colorField").value;
// Convert the hexadecimal value to RGB values
var redValue = parseInt(hexValue.substring(0, 2), 16);
var greenValue = parseInt(hexValue.substring(2, 4), 16);
var blueValue = parseInt(hexValue.substring(4, 6), 16);
// Loop through all page items in the document
for (var i = 0; i < this.numPages; i++) {
var currentPage = this.getPageNumWords(i);
for (var j = 0; j < currentPage.length; j++) {
var currentItem = currentPage[j];
// Check if the current item is a shape object
if (currentItem.typename === "PathItem") {
// Change the fill color of the shape to the user-entered color
currentItem.fillColor = [redValue / 255, greenValue / 255, blueValue / 255];
// Check the brightness of the new color
var brightness = (redValue * 299 + greenValue * 587 + blueValue * 114) / 1000;
// Loop through all text items on the current page
for (var k = 0; k < currentPage.length; k++) {
var textItem = currentPage[k];
// Check if the text item is above the current shape
if (textItem.typename === "TextFrame" && textItem.geometricBounds[1] < currentItem.geometricBounds[1]) {
// Change the color of the text to black or white depending on the brightness of the shape color
if (brightness > 128) {
textItem.fillColor = color.black;
} else {
textItem.fillColor = color.white;
}
}
}
} else if (currentItem.typename === "TextFrame") {
// Check if the current text item has the [color] marker
var contents = currentItem.contents;
if (contents.indexOf("[color]") !== -1) {
// Remove the marker and set the fill color to the user-entered color
contents = contents.replace("[color]", "");
currentItem.contents = contents;
currentItem.fillColor = [redValue / 255, greenValue / 255, blueValue / 255];
}
}
}
}
}
I added this code as a 'mouse up' trigger on the exported PDF, but sadly nothing happens at all upon button click.
Any help with this would be very much appreciated.
In order to achieve this, text fields need to be the target of the colour change, instead of shapes, and the code has been simplified. Firstly, this document-level code needs to be added to remove the standard blue 'highlight' for text fields so the colour change is visible:
//Remove standard light blue field colour
app.runtimeHighlight = false;
Then the following code reads and converts the hex colour code entered into the 'myHexColorField' text field and changes the fill colour of all text fields named 'myTextField'.
Additionally, all text fields named 'textColorToChange' will have their text colour changed to white or black, depending on the lightness of the new fill colour.
// Get the hex value from the hex text field
var hexValue = getField("myHexColorField").valueAsString;
// Convert the hexadecimal value to RGB values
var redValue = parseInt(hexValue.substring(0, 2), 16);
var greenValue = parseInt(hexValue.substring(2, 4), 16);
var blueValue = parseInt(hexValue.substring(4, 6), 16);
var redRgb = redValue / 255;
var greenRgb = greenValue / 255;
var blueRgb = blueValue / 255;
// Apply the colour change
this.getField("myTextField").fillColor = ["RGB", redRgb, greenRgb, blueRgb];
// Get the text fields that need text color change
var textField = getField("textColorToChange");
// Calculate the lightness value of the new colour fill
var lightness = redRgb + greenRgb + blueRgb;
// Set the text colour of the text field based on the lightness value
if (lightness > 1.5) {
// If the lightness is greater than 1.5, set the text colour to black
textField.textColor = color.black;
} else {
// If the lightness is less than or equal to 1.5, set the text colour to white
textField.textColor = color.white;
}
This code can be applied either to a button as a 'mouse up' action, or to the hex code text field itself as an 'on blur' action.
Thanks to K J for the help in producing this code.