186 lines
6.9 KiB
JavaScript
186 lines
6.9 KiB
JavaScript
|
|
/////////////////////////////////////////////////////////////////
|
|
// Custom Swatch Information Script for Illustrator
|
|
// Copyright SebVTL
|
|
// Supports Pantone, RGB, CMYK, HSL, and Hex values.
|
|
// Handles Global Colors and renames temporary layers to "info-couleurs".
|
|
// Generates text with color details inside selected shapes.
|
|
// Adapts text color for strong contrast with background.
|
|
// Creates temporary layer directly above the selected shape's layer.
|
|
// Adds dynamic padding for text based on the size of the selected shape.
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
var doc = app.activeDocument;
|
|
|
|
if (doc.selection.length > 0) {
|
|
for (var i = 0; i < doc.selection.length; i++) {
|
|
var selectedItem = doc.selection[i];
|
|
if (selectedItem.typename !== "PathItem") continue;
|
|
|
|
var fillColor = selectedItem.fillColor;
|
|
var activeLayer = selectedItem.layer;
|
|
|
|
// Unlock the active layer if locked
|
|
if (activeLayer.locked) activeLayer.locked = false;
|
|
|
|
// Ensure a temporary layer is created above the active layer
|
|
var tempLayer = getOrCreateLayerAbove("info-couleurs", activeLayer);
|
|
|
|
// Extract color details
|
|
var colorDetails = getColorDetails(fillColor);
|
|
if (!colorDetails) continue;
|
|
|
|
// Create text frame with color information
|
|
createTextFrameWithPadding(selectedItem, colorDetails, tempLayer);
|
|
}
|
|
}
|
|
|
|
// Function to create or get a layer directly above the specified layer
|
|
function getOrCreateLayerAbove(layerName, referenceLayer) {
|
|
var newLayer = null;
|
|
|
|
// Check if a layer with the specified name already exists above the reference layer
|
|
for (var j = 0; j < doc.layers.length; j++) {
|
|
if (doc.layers[j].name === layerName && doc.layers[j].zOrderPosition > referenceLayer.zOrderPosition) {
|
|
return doc.layers[j]; // Return the existing layer
|
|
}
|
|
}
|
|
|
|
// Create a new layer and move it above the reference layer
|
|
newLayer = doc.layers.add();
|
|
newLayer.name = layerName;
|
|
newLayer.move(referenceLayer, ElementPlacement.PLACEBEFORE);
|
|
return newLayer;
|
|
}
|
|
|
|
// Function to extract color details
|
|
function getColorDetails(color) {
|
|
var details = {
|
|
pantone: "N/A",
|
|
rgb: { red: 0, green: 0, blue: 0 },
|
|
cmyk: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
|
|
hsl: "H:0 S:0 L:0",
|
|
hex: "#000000"
|
|
};
|
|
|
|
if (color.typename === "SpotColor" || color.typename === "GlobalColor") {
|
|
details.pantone = color.spot ? color.spot.name || "N/A" : "N/A";
|
|
if (color.spot && color.spot.color.rgb) {
|
|
details.rgb = color.spot.color.rgb;
|
|
details.hex = rgbToHex(details.rgb.red, details.rgb.green, details.rgb.blue);
|
|
}
|
|
if (color.spot && color.spot.color.cmyk) details.cmyk = color.spot.color.cmyk;
|
|
if (color.spot && color.spot.color.hue !== undefined) {
|
|
details.hsl = "H:" + Math.round(color.spot.color.hue || 0) +
|
|
" S:" + Math.round(color.spot.color.saturation || 0) +
|
|
" L:" + Math.round(color.spot.color.lightness || 0);
|
|
}
|
|
} else if (color.typename === "RGBColor") {
|
|
details.rgb = color;
|
|
details.cmyk = convertToCMYK(color);
|
|
details.hsl = convertToHSL(color);
|
|
details.hex = rgbToHex(color.red, color.green, color.blue);
|
|
} else if (color.typename === "CMYKColor") {
|
|
details.cmyk = color;
|
|
details.rgb = convertToRGB(color);
|
|
details.hsl = convertToHSL(details.rgb);
|
|
details.hex = rgbToHex(details.rgb.red, details.rgb.green, details.rgb.blue);
|
|
} else {
|
|
return null;
|
|
}
|
|
|
|
return details;
|
|
}
|
|
|
|
// Function to create a text frame with dynamic padding
|
|
function createTextFrameWithPadding(item, colorDetails, targetLayer) {
|
|
var content = "Pantone: " + colorDetails.pantone + "\n" +
|
|
"RVB: " + Math.round(colorDetails.rgb.red) + ", " + Math.round(colorDetails.rgb.green) + ", " + Math.round(colorDetails.rgb.blue) + "\n" +
|
|
"CMJN: " + Math.round(colorDetails.cmyk.cyan) + "%, " + Math.round(colorDetails.cmyk.magenta) + "%, " + Math.round(colorDetails.cmyk.yellow) + "%, " + Math.round(colorDetails.cmyk.black) + "%\n" +
|
|
"TLS: " + colorDetails.hsl + "\n" +
|
|
"Hex: " + colorDetails.hex;
|
|
|
|
// Calculate dynamic padding based on the item's dimensions
|
|
var paddingX = item.width * 0.1; // 10% of the item's width
|
|
var paddingY = item.height * 0.1; // 10% of the item's height
|
|
|
|
|
|
// Définir explicitement le calque temporaire comme calque actif
|
|
app.activeDocument.activeLayer = targetLayer;
|
|
if (targetLayer.locked) targetLayer.locked = false;
|
|
if (!targetLayer.visible) targetLayer.visible = true;
|
|
|
|
var textFrame = doc.textFrames.add();
|
|
|
|
textFrame.contents = content;
|
|
textFrame.position = [item.left + paddingX, item.top - paddingY];
|
|
|
|
var textColor = new RGBColor();
|
|
if (isDarkColor(colorDetails.rgb)) {
|
|
textColor.red = 255;
|
|
textColor.green = 255;
|
|
textColor.blue = 255;
|
|
} else {
|
|
textColor.red = 0;
|
|
textColor.green = 0;
|
|
textColor.blue = 0;
|
|
}
|
|
textFrame.textRange.fillColor = textColor;
|
|
|
|
// Move the text frame to the target layer
|
|
textFrame.move(targetLayer, ElementPlacement.PLACEATBEGINNING);
|
|
}
|
|
|
|
// Utility functions
|
|
function rgbToHex(r, g, b) {
|
|
function componentToHex(c) {
|
|
var hex = Math.round(c).toString(16);
|
|
return hex.length === 1 ? "0" + hex : hex;
|
|
}
|
|
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
|
|
}
|
|
|
|
function convertToRGB(cmyk) {
|
|
return {
|
|
red: (1 - cmyk.cyan / 100) * (1 - cmyk.black / 100) * 255,
|
|
green: (1 - cmyk.magenta / 100) * (1 - cmyk.black / 100) * 255,
|
|
blue: (1 - cmyk.yellow / 100) * (1 - cmyk.black / 100) * 255
|
|
};
|
|
}
|
|
|
|
function convertToCMYK(rgb) {
|
|
var r = rgb.red / 255, g = rgb.green / 255, b = rgb.blue / 255;
|
|
var k = 1 - Math.max(r, g, b);
|
|
if (k === 1) return { cyan: 0, magenta: 0, yellow: 0, black: 100 };
|
|
return {
|
|
cyan: ((1 - r - k) / (1 - k)) * 100 || 0,
|
|
magenta: ((1 - g - k) / (1 - k)) * 100 || 0,
|
|
yellow: ((1 - b - k) / (1 - k)) * 100 || 0,
|
|
black: k * 100
|
|
};
|
|
}
|
|
|
|
function convertToHSL(rgb) {
|
|
var r = rgb.red / 255, g = rgb.green / 255, b = rgb.blue / 255;
|
|
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
|
var h, s, l = (max + min) / 2;
|
|
|
|
if (max == min) {
|
|
h = s = 0;
|
|
} else {
|
|
var d = max - min;
|
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
switch (max) {
|
|
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
|
case g: h = (b - r) / d + 2; break;
|
|
case b: h = (r - g) / d + 4; break;
|
|
}
|
|
h /= 6;
|
|
}
|
|
return "H:" + Math.round(h * 360) + " S:" + Math.round(s * 100) + " L:" + Math.round(l * 100);
|
|
}
|
|
|
|
function isDarkColor(color) {
|
|
return (color.red * 0.299 + color.green * 0.587 + color.blue * 0.114) < 128;
|
|
}
|