Hi m1b.
Thank you very much.
It says settings is undefined, so I did it this way
var settings;
myDisplayDialog(settings); var settings.
I want to draw a reference line at (myX1 + myMouthWidth), what should I write?
Hey @dublove I find the functions not easy to use for me, so I've refactored the code—not as much as I want to, but at least to make it easier to work with (I hope!). In this version I removed all the "my" variables—unnecessary!—and cleaned up a few things here and there, but mostly I made better functions for creating the lines and registration target marks.
And I added in a couple of lines to draw the mouth lines. See what you think.
- Mark
/* CropMarks.jsx
Draws crop and/or registration marks around the selected object or objects.
For more on InDesign scripting, go to http://www.adobe.com/products/indesign/scripting.html
or visit the InDesign Scripting User to User forum at http://www.adobeforums.com
Based on CropMarks.jsx
Modified by dublove
Modified 2025-03-28 by m1b
*/
function main() {
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
var mm = 2.83465;
if (app.documents.length === 0)
return alert("Ple请打开一个文档,选择一个物体再试,呵呵");
if (app.selection.length == 0)
return alert("请选择一个物体再试,呵呵.");
if (!app.selection[0].geometricBounds)
return alert("选择一个页面消息再试.");
var doc = app.activeDocument;
// create dialog
var dialog = app.dialogs.add({ name: "DrawCropMarks" });
with (dialog) {
with (dialogColumns.add()) {
var cropMarksGroup = enablingGroups.add({ staticLabel: "CropMarks", checkedState: true });
with (cropMarksGroup) {
with (borderPanels.add()) {
staticTexts.add({ staticLabel: "Option:" });
with (dialogColumns.add()) {
staticTexts.add({ staticLabel: "lengths:" });
staticTexts.add({ staticLabel: "offset:" });
staticTexts.add({ staticLabel: "Thickness:" });
staticTexts.add({ staticLabel: "Spine:" });
staticTexts.add({ staticLabel: "Mouth:" });
}
with (dialogColumns.add()) {
//看到的界面单位是毫米,运算前的值为点,所以要奖毫米折算为点(即,毫米值乘于2.8345)进行
var cropMarkLengthField = measurementEditboxes.add({ editValue: (3 * mm), editUnits: MeasurementUnits.millimeters });
var cropMarkOffsetField = measurementEditboxes.add({ editValue: (3 * mm), editUnits: MeasurementUnits.millimeters });
var cropMarkWidthField = measurementEditboxes.add({ editValue: (0.1 * mm), editUnits: MeasurementUnits.millimeters });
//新增 书脊 勒口
var spineWidthField = measurementEditboxes.add({ editValue: (20 * mm), editUnits: MeasurementUnits.millimeters });
var mouthWidthField = measurementEditboxes.add({ editValue: (83 * mm), editUnits: MeasurementUnits.millimeters });
}
}
}
var regMarksGroup = enablingGroups.add({ staticLabel: "alignment mark", checkedState: true });
with (regMarksGroup) {
with (borderPanels.add()) {
staticTexts.add({ staticLabel: "Option:" });
with (dialogColumns.add()) {
staticTexts.add({ staticLabel: "inner radius:" });
staticTexts.add({ staticLabel: "outer radius:" });
staticTexts.add({ staticLabel: "offset:" });
}
with (dialogColumns.add()) {
var regMarkInnerRadiusField = measurementEditboxes.add({ editValue: (2.8345 * 1), editUnits: MeasurementUnits.millimeters });
var regMarkOuterRadiusField = measurementEditboxes.add({ editValue: (2.8345 * 1.5), editUnits: MeasurementUnits.millimeters });
var regMarkOffsetField = measurementEditboxes.add({ editValue: 0, editUnits: MeasurementUnits.millimeters });
}
}
}
with (borderPanels.add()) {
staticTexts.add({ staticLabel: "Range for drawing:" });
var rangeButtons = radiobuttonGroups.add();
with (rangeButtons) {
radiobuttonControls.add({ staticLabel: "Every object", checkedState: true });
radiobuttonControls.add({ staticLabel: "whole selection" });
}
}
}
}
// show the dialog
var result = dialog.show();
//Get the values from the dialog box.从对话框获取
var doCropMarks = cropMarksGroup.checkedState;
var doRegMarks = regMarksGroup.checkedState;
var cropMarkLength = cropMarkLengthField.editValue;
var cropMarkOffset = cropMarkOffsetField.editValue;
var cropMarkWidth = cropMarkWidthField.editValue;
var regMarkInnerRadius = regMarkInnerRadiusField.editValue;
var regMarkOuterRadius = regMarkOuterRadiusField.editValue;
var regMarkOffset = regMarkOffsetField.editValue;
//书脊和勒口
var spineWidth = spineWidthField.editValue;
var mouthWidth = mouthWidthField.editValue;
var range = rangeButtons.selectedButton;
dialog.destroy();
if (!result)
// user cancelled
return;
//"||" is logical OR in JavaScript.
if (!doCropMarks && !doRegMarks)
return alert("No printers marks were selected.");
//Create a layer to hold the printers marks (if it does not already exist).
var layer = doc.layers.item("cropMarks");
if (!layer.isValid)
layer = doc.layers.add({ name: "cropMarks" });
//Get references to the Registration color and the None swatch.
var registrationColor = doc.colors.item("Registration");
var noneSwatch = doc.swatches.item("None");
// these are the bounds we will add cropmarks to
var allBounds = [];
// get bounds of selection
var items = doc.selection;
for (var i = 0; i < items.length; i++)
allBounds.push(items[i].visibleBounds);
if (range === 1)
// combine all the item bounds into one bound
allBounds = [combineBounds(allBounds)];
// loop over the bounds and draw the marks
for (var i = 0; i < allBounds.length; i++) {
var bounds = allBounds[i];
if (doCropMarks == true) {
drawCropMarks(bounds, doc);
}
if (doRegMarks == true) {
drawRegMarks(bounds, doc);
}
}
function drawCropMarks(bounds, group) {
var x1 = bounds[1],
y1 = bounds[0],
x2 = bounds[3],
y2 = bounds[2];
var props = {
filled: false,
stroked: true,
strokeColor: registrationColor,
strokeWeight: cropMarkWidth,
};
//Create a group for the marks (we need)
var tmp1 = doc.layoutWindows[0].activePage.graphicLines.add();
var tmp2 = doc.layoutWindows[0].activePage.graphicLines.add();
var group = doc.layoutWindows[0].activePage.groups.add([tmp1, tmp2], layer);
// dublove, this is where you are currently working
var xCenterA = x1 + ((x2 - x1) / 2);
var yCenterA = y1 + ((y2 - y1) / 2);
var spineLeft = xCenterA - (20 / 2);
var spineRight = xCenterA + (20 / 2);
//Drawmouth 画勒口线
drawGraphicLine([x1 + mouthWidth, y1], [x1 + mouthWidth, y1 - cropMarkLength], group, props);
drawGraphicLine([x1 + mouthWidth, y2], [x1 + mouthWidth, y2 + cropMarkLength], group, props);
//Upper left crop mark pair.左上角
drawGraphicLine([x1, y1], [x1 - cropMarkLength, y1], group, props);
drawGraphicLine([x1, y1 + cropMarkOffset], [x1 - cropMarkLength, y1 + cropMarkOffset], group, props);
drawGraphicLine([x1, y1], [x1, y1 - cropMarkLength], group, props);
drawGraphicLine([x1 + cropMarkOffset, y1], [x1 + cropMarkOffset, y1 - cropMarkLength], group, props);
//Lower left crop mark pair.左下角
drawGraphicLine([x2, y1], [x2 + cropMarkLength, y1], group, props);
drawGraphicLine([x2 - cropMarkOffset + cropMarkOffset, y1 + cropMarkOffset], [x2 - cropMarkOffset + cropMarkOffset + cropMarkLength, y1 + cropMarkOffset], group, props);
drawGraphicLine([x2, y1], [x2, y1 - cropMarkLength], group, props);
drawGraphicLine([x2 - cropMarkOffset, y1], [x2 - cropMarkOffset, y1 - cropMarkLength], group, props);
//Upper right crop mark pair.右上角
drawGraphicLine([x1, y2], [x1 - cropMarkLength, y2], group, props);
drawGraphicLine([x1, y2 - cropMarkOffset], [x1 - cropMarkLength, y2 - cropMarkOffset], group, props);
drawGraphicLine([x1, y2], [x1, y2 + cropMarkLength], group, props);
drawGraphicLine([x1 + cropMarkOffset, y2], [x1 + cropMarkOffset, y2 + cropMarkLength], group, props);
//Lower right crop mark pair.右下角
drawGraphicLine([x2, y2], [x2 + cropMarkLength, y2], group, props);
drawGraphicLine([x2, y2 - cropMarkOffset], [x2 + cropMarkLength, y2 - cropMarkOffset], group, props);
drawGraphicLine([x2, y2], [x2, y2 + cropMarkLength], group, props);
drawGraphicLine([x2 - cropMarkOffset, y2], [x2 - cropMarkOffset, y2 + cropMarkLength], group, props);
// cleanup the temporary items in the group
tmp2.remove();
tmp1.remove();
return group;
};
//画圆十字
function drawRegMarks(bounds, container) {
var x1 = bounds[1],
y1 = bounds[0],
x2 = bounds[3],
y2 = bounds[2];
var cx = x1 + ((x2 - x1) / 2);
var cy = y1 + ((y2 - y1) / 2);
var offset = regMarkOffset + regMarkOuterRadius;
var props = {
filled: false,
stroked: true,
strokeColor: registrationColor,
strokeWeight: cropMarkWidth,
};
var registrationTargetItems = [
//Top registration target.上方圆
drawRegistrationTarget([cx, y1 - offset], regMarkInnerRadius, regMarkOuterRadius, container, props),
//Bottom registration target.下方圆
drawRegistrationTarget([cx, y2 + offset], regMarkInnerRadius, regMarkOuterRadius, container, props),
//Left registration target.左侧圆
drawRegistrationTarget([x1 - offset, cy], regMarkInnerRadius, regMarkOuterRadius, container, props),
//Right registration target.右侧圆
drawRegistrationTarget([x2 + offset, cy], regMarkInnerRadius, regMarkOuterRadius, container, props),
];
var group = container.groups.add(registrationTargetItems);
group.itemLayer = layer;
return group;
};
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Add Cropmarks');
/**
* Returns a registration target symbol.
* @author m1b
* @version 2025-03-28
* @param {Array<Number>} center - the center of the target [x, y].
* @param {Number} radius - the radius of the circle, in points.
* @param {Number} lineSize - the length of the lines from the center, in points.
* @param {Document|Page|Spread} container - the place to draw the line
* @param {Object} [props] - properties to apply to the new line (default: no properties)
* @returns {Group}
*/
function drawRegistrationTarget(center, circleRadius, lineSize, container, props) {
props = props || {};
var parts = [],
x = center[0],
y = center[1];
// lines
parts.push(drawGraphicLine([x - lineSize, y], [x + lineSize, y], container, props))
parts.push(drawGraphicLine([x, y - lineSize], [x, y + lineSize], container, props))
// circle
parts.push(drawCircle(center, circleRadius, container, props))
// return group
return container.groups.add(parts);
};
/**
* Returns a new circle.
* @author m1b
* @version 2025-03-28
* @param {Array<Number>} center - the center of the circle [x, y].
* @param {Number} radius - the radius of the circle, in points.
* @param {Document|Page|Spread} container - the place to draw the line
* @param {Object} [props] - properties to apply to the new line (default: no properties)
* @returns {Oval}
*/
function drawCircle(center, radius, container, props) {
var circle = container.ovals.add();
circle.geometricBounds = [center[1] - radius, center[0] - radius, center[1] + radius, center[0] + radius];
circle.properties = props || {};
return circle;
};
/**
* Returns a new graphic line.
* @author m1b
* @version 2025-03-28
* @param {Array<Number>} p0 - the first point [x, y].
* @param {Array<Number>} p1 - the second point [x, y].
* @param {Document|Page|Spread} container - the place to draw the line
* @param {Object} [props] - properties to apply to the new line (default: no properties)
* @returns {GraphicLine}
*/
function drawGraphicLine(p0, p1, container, props) {
var newLine = container.graphicLines.add();
newLine.paths.item(0).pathPoints.item(0).anchor = p0;
newLine.paths.item(0).pathPoints.item(1).anchor = p1;
newLine.properties = props || {};
return newLine;
};
/**
* Returns the combined bounds of all bounds supplied.
* Works with Illustrator or Indesign bounds.
* @author m1b
* @version 2024-03-09
* @param {Array<bounds>} boundsArray - an array of bounds [L, T, R, B] or [T, L , B, R].
* @returns {bounds?} - the combined bounds.
*/
function combineBounds(boundsArray) {
var combinedBounds = boundsArray[0].slice(),
comparator;
if (/indesign/i.test(app.name))
comparator = [Math.min, Math.min, Math.max, Math.max];
else if (/illustrator/i.test(app.name))
comparator = [Math.min, Math.max, Math.max, Math.min];
// iterate through the rest of the bounds
for (var i = 1; i < boundsArray.length; i++) {
var bounds = boundsArray[i];
combinedBounds = [
comparator[0](combinedBounds[0], bounds[0]),
comparator[1](combinedBounds[1], bounds[1]),
comparator[2](combinedBounds[2], bounds[2]),
comparator[3](combinedBounds[3], bounds[3]),
];
}
return combinedBounds;
};
Edit 2025-05-21: fixed bug where temp lines weren't created on the correct page.