[AI CC-CC2023] Не получается задать overprint для pathItem-a

romaya

Топикстартер
10 лет на форуме
Сообщения
341
Реакции
41
Добрый день!

Который день бьюсь над задачей, но никак не могу найти решения. Надо скриптом задать overprint для заливки и обводки одного объекта. Не выходит "каменный цветок". Не пойму почему. Может кто поможет советом? Ниже весь код. Смотреть функцию duplicatePrintBoxToWhiteLayer(). Тестирую в AI CC 2019 и 2021. Заранее спасибо всем неравнодушным)

JavaScript:
// add_white_ink.jsx
#target illustrator

function main() {
    if (app.documents.length === 0) {
        alert("Нет открытых документов!");
        return;
    }

    var doc = app.activeDocument;
    var layers = doc.layers;
    var whiteLayerName = "White";
    var whiteLayer = findLayerByName(layers, whiteLayerName);

    if (!whiteLayer) {
        whiteLayer = createLayerInCorrectPosition(doc, whiteLayerName);
    }

    if (!whiteLayer) return;

    var schemaLayer = findLayerByName(layers, "Schema");
    if (!schemaLayer) {
        alert("Слой 'Schema' не найден!");
        return;
    }

    var printBox = findPrintBoxInSchema(schemaLayer);
    if (!printBox) {
        alert("Объект 'printBox' не найден!");
        return;
    }

    if (printBox.typename !== "PathItem" && printBox.typename !== "CompoundPathItem") {
        alert("Объект printBox должен быть контуром!");
        return;
    }

    var whiteColor = getOrCreateSpotWhiteColor(doc);
    if (!whiteColor) return;

    if (checkIfWhiteInkExists(whiteLayer)) {
        if (!confirm("На слое 'White' уже есть белила. Создать новые?")) {
            return;
        }
        removeExistingWhiteInk(whiteLayer);
    }

    if (duplicatePrintBoxToWhiteLayer(whiteLayer, printBox, whiteColor)) {
        alert("Белила успешно добавлены!");
    }
}

function createLayerInCorrectPosition(doc, layerName) {
    try {
        var layers = doc.layers;
        var workTextLayer = findLayerByName(layers, "WorkText");
        var workLayer = findLayerByName(layers, "Work");
        var newLayer = layers.add();
        newLayer.name = layerName;

        if (workTextLayer) {
            newLayer.move(workTextLayer, ElementPlacement.PLACEBEFORE);
        } else if (workLayer) {
            newLayer.move(workLayer, ElementPlacement.PLACEBEFORE);
        } else if (layers.length > 1) {
            var targetPosition = layers.length - 1;
            newLayer.move(layers[targetPosition], ElementPlacement.PLACEBEFORE);
        }

        return newLayer;
    } catch (e) {
        return null;
    }
}

function findLayerByName(layers, layerName) {
    var lowerName = layerName.toLowerCase();
    for (var i = 0; i < layers.length; i++) {
        if (layers[i].name.toLowerCase() === lowerName) {
            return layers[i];
        }
    }
    return null;
}

function findPrintBoxInSchema(schemaLayer) {
    for (var i = 0; i < schemaLayer.pageItems.length; i++) {
        var item = schemaLayer.pageItems[i];
        if (item.name === "printBox") return item;
        if (item.typename === "GroupItem") {
            var found = findItemInGroup(item, "printBox");
            if (found) return found;
        }
    }
    return null;
}

function findItemInGroup(group, itemName) {
    for (var i = 0; i < group.pageItems.length; i++) {
        var item = group.pageItems[i];
        if (item.name === itemName) return item;
        if (item.typename === "GroupItem") {
            var found = findItemInGroup(item, itemName);
            if (found) return found;
        }
    }
    return null;
}

function checkIfWhiteInkExists(whiteLayer) {
    for (var i = 0; i < whiteLayer.pathItems.length; i++) {
        if (whiteLayer.pathItems[i].name === "white_ink") {
            return true;
        }
    }
    return false;
}

function removeExistingWhiteInk(whiteLayer) {
    for (var i = whiteLayer.pathItems.length - 1; i >= 0; i--) {
        if (whiteLayer.pathItems[i].name === "white_ink") {
            whiteLayer.pathItems[i].remove();
        }
    }
}

function getOrCreateSpotWhiteColor(doc) {
    // 1. Сначала очищаем все swatch с именем "White"
    for (var i = doc.swatches.length - 1; i >= 0; i--) {
        if (doc.swatches[i].name === "White") {
            doc.swatches[i].remove();
        }
    }

    // 2. Удаляем spot "White" если он есть
    for (var i = doc.spots.length - 1; i >= 0; i--) {
        if (doc.spots[i].name === "White") {
            doc.spots[i].remove();
        }
    }

    // 3. Создаем новый spot color с нуля
    return createSpotWhiteColor(doc);
}

function createSpotWhiteColor(doc) {
    try {
        // Создаем CMYK цвет
        var cmykColor = new CMYKColor();
        cmykColor.cyan = 30;
        cmykColor.magenta = 0;
        cmykColor.yellow = 0;
        cmykColor.black = 0;

        // Создаем новый спот
        var newSpot = doc.spots.add();
        newSpot.name = "White";
        newSpot.color = cmykColor;

        // Создаем SpotColor объект
        var spotColor = new SpotColor();
        spotColor.spot = newSpot;
        spotColor.tint = 100;

        // Создаем swatch
        var newSwatch = doc.swatches.add();
        newSwatch.name = "White";
        newSwatch.color = spotColor;

        return spotColor;
    } catch (e) {
        return null;
    }
}

function updateSwatch(doc, swatchName, color) {
    // Удаляем все swatch с таким именем
    for (var i = doc.swatches.length - 1; i >= 0; i--) {
        if (doc.swatches[i].name === swatchName) {
            doc.swatches[i].remove();
        }
    }

    // Создаем новый swatch с правильным цветом
    var newSwatch = doc.swatches.add();
    newSwatch.name = swatchName;
    newSwatch.color = color;
}

function createSpotWhiteColor(doc) {
    try {
        // Создаем CMYK цвет
        var cmykColor = new CMYKColor();
        cmykColor.cyan = 30;
        cmykColor.magenta = 0;
        cmykColor.yellow = 0;
        cmykColor.black = 0;

        // Создаем новый спот (это самое важное!)
        var newSpot = doc.spots.add();
        newSpot.name = "White";
        newSpot.colorType = ColorModel.SPOT;
        newSpot.color = cmykColor;

        // Создаем SpotColor объект с 100% тинтингом
        var spotColor = new SpotColor();
        spotColor.spot = newSpot;
        spotColor.tint = 100;

        // Создаем swatch с этим Spot Color
        createSwatchIfNotExists(doc, "White", spotColor);

        return spotColor;
    } catch (e) {
        return null;
    }
}

function createSwatchIfNotExists(doc, swatchName, color) {
    for (var i = 0; i < doc.swatches.length; i++) {
        if (doc.swatches[i].name === swatchName) {
            doc.swatches[i].color = color;
            return;
        }
    }
    var newSwatch = doc.swatches.add();
    newSwatch.name = swatchName;
    newSwatch.color = color;
}

function duplicatePrintBoxToWhiteLayer(whiteLayer, printBox, whiteColor) {
    var oldActiveLayer = app.activeDocument.activeLayer;

    try {
        printBox.locked = false;
        printBox.layer.locked = false;
        whiteLayer.locked = false;

        app.activeDocument.activeLayer = printBox.layer;
        var whiteInk = printBox.duplicate();
        whiteInk.move(whiteLayer, ElementPlacement.PLACEATEND);
        whiteInk.name = "white_ink";
        whiteInk.fillColor = whiteColor;
        whiteInk.filled = true;
        whiteInk.stroked = true;
        whiteInk.fillOverprint = true;
        whiteInk.strokeOverprint = true;

        var strokeWhiteColor = new SpotColor();
        strokeWhiteColor.spot = whiteColor.spot;
        strokeWhiteColor.tint = 0;

        whiteInk.strokeColor = strokeWhiteColor;
        whiteInk.strokeWidth = 0.3 * 2.83464566929134;
        whiteInk.strokeAlignment = 0;

        whiteInk.selected = false;
        app.activeDocument.activeLayer = oldActiveLayer;
        return true;

    } catch (e) {
        app.activeDocument.activeLayer = oldActiveLayer;
        return false;
    }
}

main();
 
Для тестов нужно создать слой Schema, нарисовать на нем прямоугольник и назвать его printBox.
 
Вроде работает. Иллюстратор 2024 (28.6).
1768305083549.png
 
  • Спасибо
Реакции: romaya
Замечательно! Мне нужно чтобы в AI CC 2021 работал)
 
Действительно, работает в обеих версиях. Аллилуйя!
 
Не понятно в первом сообщении в чем проблема. "Бьюсь который день" и метафора "Не выходит "каменный цветок". Что именно не выходит, где обрыв алгоритма у тебя на тесте: не создался спот? не добавился цвет, обводка? не применилось свойство оверпринта?
 
Не понятно в первом сообщении в чем проблема. "Бьюсь который день" и метафора "Не выходит "каменный цветок". Что именно не выходит и на каком шаге: не создался спот? не добавился цвет, обводка? не применилось свойство оверпринта?
Оверпринт не устанавливался.
 
Проверил в рандомных версиях АИ старее и новее на Маке и Вин. Везде работает стабильно.
 
  • Спасибо
Реакции: romaya
Отлично, спасибо. Я чего-то загнался слегка, прошу прощения. С живыми людьми захотелось пообщаться, а так мы с DeepSeek-ом скрипт пилили)