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

  • Автор темы Автор темы romaya
  • Дата начала Дата начала

romaya

Топикстартер
10 лет на форуме
Сообщения
343
Реакции
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-ом скрипт пилили)