Hallo,
Hier ein Skript mit dem man spirograph-ähnliche Formen direkt in InDesign erstellen kann. Das Skript stammt aus dem Buch RealWorld inDesign CS2 von David Blatner und Olav-Martin Kvern. Ich habe das Skript auf Nachfrage hin geschickt bekommen und ich denke es könnte vielleicht für den einen oder anderen nützlich sein.
Das Skript heisst NINAs (Nina is not an acronym)
Dann noch das Skript MysticRose mit dem ähnliche Effekte erzielt werden.
Gruß, Siuloong
//NINAs.jsx
//An InDesign CS2 JavaScript
//
//Draws a NINA geometric object.
//
//For more on NINA, see http://www.washington.edu/bibsys/mattf/nina/index.html
//myNumberOfLines sets the number of line segments in the NINA.
main();
function main(){
myDisplayDialog();
}
function myDisplayDialog(){
var myDialog = app.dialogs.add({name:"NINA"});
with(myDialog){
//Add a dialog column.
var myDialogColumn = dialogColumns.add()
with(myDialogColumn){
with(borderPanels.add()){
with(dialogColumns.add()){
staticTexts.add({staticLabel:"Number of iterations:"}) ;
staticTexts.add({staticLabel:"a_pulse:"});
staticTexts.add({staticLabel:"b_pulse:"});
staticTexts.add({staticLabel:"Line length (in points):"});
}
with(dialogColumns.add()){
//The following line shows how to set multiple properties as you create an object.
//201:16:161:72 makes a nice example NINA.
var myNumberOfLinesField = integerEditboxes.add({editValue:201, minWidth:60});
var myAPulseField = integerEditboxes.add({editValue:16, minWidth:60});
var myBPulseField = integerEditboxes.add({editValue:161, minWidth:60});
var myLengthField = integerEditboxes.add({editValue:72, minWidth:60});
}
}
with(borderPanels.add()){
with(radiobuttonGroups.add()){
var myClosedPathButton = radiobuttonControls.add({staticLabel:"Closed path", checkedState:true});
var myOpenPathButton = radiobuttonControls.add({staticLabel:"Open path"});
}
}
}
}
var myReturn = myDialog.show();
if (myReturn == true){
//Get the values from the dialog box.
var myNumberOfLines = myNumberOfLinesField.editValue;
var a_pulse = myAPulseField.editValue;
var b_pulse = myBPulseField.editValue;
var myLength = myLengthField.editValue;
var myOpenPath = myOpenPathButton.checkedState;
myDialog.destroy();
myDrawNINA(myNumberOfLines, a_pulse, b_pulse, myLength, myOpenPath);
}
else{
myDialog.destroy();
}
}
function myDrawNINA(myNumberOfLines, a_pulse, b_pulse, myLength, myOpenPath){
var cur_x, cur_y;
var myAnchor = new Array(2);
var myArray = new Array(myNumberOfLines);
//Fill in the Array "myArray" with a list of coordinates.
for (var myCounter = 0; myCounter < myNumberOfLines; myCounter++){
cur_x = (Math.cos((-2 * Math.PI * a_pulse * myCounter) / myNumberOfLines) + Math.cos((-2 * Math.PI * b_pulse * myCounter) / myNumberOfLines)) * myLength
cur_y = (Math.sin((-2 * Math.PI * a_pulse * myCounter) / myNumberOfLines) + Math.sin((-2 * Math.PI * b_pulse * myCounter) / myNumberOfLines)) * myLength
myAnchor = [cur_x, cur_y];
myArray[myCounter] = myAnchor;
}
var myDocument = app.documents.item(0);
with(myDocument){
viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
var myPage = pages.item(0)
with(myPage){
var myGraphicLine = graphicLines.add();
var myPath = myGraphicLine.paths.item(0);
myPath.entirePath = myArray;
if (myOpenPath == false){
myPath.pathType = PathType.closedPath;
}
//Label the object with the NINA settings.
myGraphicLine.label = myNumberOfLines + ":" + a_pulse + ":" + b_pulse + ":" + myLength
}
}
}
//MysticRose.jsx
//An InDesign CS2 JavaScript
//
//Draws a "mystic rose" geometric pattern, a type of construction also
//known as "string art".
//
if(app.documents.length!=0){
if(app.activeWindow.constructor.name == "LayoutWindow"){
var myArray = myDisplayDialog();
var myDrawRose = myArray[0];
if(myDrawRose == true){
var myOldXUnits = app.activeDocument.viewPreferences.horizontalMeasurementUnits;
var myOldYUnits = app.activeDocument.viewPreferences.verticalMeasurementUnits;
app.activeDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
app.activeDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
var myCenterPoint = myArray[1];
var myNumberOfPoints = myArray[2];
var myDiameter = myArray[3];
var mySkipLength = myArray[4];
var myEvenOddFill = myArray[5];
var myPathPoints = myCalculatePolygon(myCenterPoint, myDiameter/2, myNumberOfPoints);
myDrawMagicRose(myPathPoints, mySkipLength, myEvenOddFill, myNumberOfPoints);
app.activeDocument.viewPreferences.horizontalMeasurementUnits = myOldXUnits;
app.activeDocument.viewPreferences.verticalMeasurementUnits = myOldYUnits;
}
}
}
function myDisplayDialog(){
var myLabelWidth = 90;
var myDialog = app.dialogs.add({name:"MysticRose"});
with(myDialog.dialogColumns.add()){
with(dialogRows.add()){
with(dialogColumns.add()){
staticTexts.add({staticLabel:"Center Point:", minWidth:myLabelWidth});
}
with(dialogColumns.add()){
staticTexts.add({staticLabel:"X:"});
}
with(dialogColumns.add()){
var myXField = measurementEditboxes.add({editValue:0, editUnits:MeasurementUnits.points});
}
}
with(dialogRows.add()){
with(dialogColumns.add()){
staticTexts.add({staticLabel:"", minWidth:myLabelWidth});
}
with(dialogColumns.add()){
staticTexts.add({staticLabel:"Y:"});
}
with(dialogColumns.add()){
var myYField = measurementEditboxes.add({editValue:0, editUnits:MeasurementUnits.points});
}
}
myLabelWidth = 115;
with(dialogRows.add()){
with(dialogColumns.add()){
staticTexts.add({staticLabel:"Diameter:", minWidth:myLabelWidth});
}
with(dialogColumns.add()){
var myDiameterField = measurementEditboxes.add({editValue:144, editUnits:MeasurementUnits.points});
}
}
with(dialogRows.add()){
with(dialogColumns.add()){
staticTexts.add({staticLabel:"Number of Points:", minWidth:myLabelWidth});
}
with(dialogColumns.add()){
var myNumberOfPointsField = integerEditboxes.add({editValue:21});
}
}
with(dialogRows.add()){
with(dialogColumns.add()){
staticTexts.add({staticLabel:"Skip Array:", minWidth:myLabelWidth});
}
with(dialogColumns.add()){
var mySkipLengthField = textEditboxes.add({editContents:"1,2,3,4,5,6,7,8,9,10"});
}
}
var myEvenOddCheckbox = checkboxControls.add({staticLabel:"Even/Odd Fill"});
}
var myResult = myDialog.show();
//Turn the skip pattern into the string version of an array.
var mySkipLength = "[" + mySkipLengthField.editContents + "]";
var myNumberOfPoints = myNumberOfPointsField.editValue;
var myDiameter = myDiameterField.editValue;
var myX = myXField.editValue;
var myY = myYField.editValue;
var myEvenOddFill = myEvenOddCheckbox.checkedState;
if(myResult == true){
myDrawRose = true;
myDialog.destroy();
}
else{
myDialog.destroy();
myDrawRose = false;
}
return [myDrawRose, [myX, myY], myNumberOfPoints, myDiameter, mySkipLength, myEvenOddFill];
}
function myDrawMagicRose(myPathPoints, mySkipArray, myEvenOddFill, myNumberOfPoints){
var myIndex;
var myNewPathPoints = new Array;
var myDone = false;
var myCounter = 1;
var myIndex = 0;
mySkipArray = eval(mySkipArray);
myNewPathPoints.push(myPathPoints[0]);
do{
for(var mySkipCounter = 0; mySkipCounter < mySkipArray.length;mySkipCounter++){
var myIndex = (myIndex + mySkipArray[mySkipCounter])%myPathPoints.length;
myNewPathPoints.push(myPathPoints[myIndex]);
}
if(myIndex == 0){
//When we reach the starting point at the end of the sequence
//of steps, we're done. Note that we can reach the starting point
//many times *inside* the step sequence.
myDone = true;
}
else{
myCounter ++;
}
}while (myDone != true);
var myPolygon = app.activeWindow.activePage.polygons.add();
myPolygon.paths.item(0).entirePath = myNewPathPoints;
if(myEvenOddFill == 1){
var myNewPolygon = myPolygon.duplicate();
myPolygon.addPath(myNewPolygon);
}
}
//Function calculates the points for an n-sided polygon around a given center point.
function myCalculatePolygon(myCenterPoint, myRadius, myNumberOfPoints){
myAngleIncrement = (360/myNumberOfPoints)*(Math.PI/180);
var myPathPoints = new Array;
for (myPointCounter = 0; myPointCounter < myNumberOfPoints;myPointCounter ++){
myX = myCenterPoint[0] + (myRadius * Math.cos(myAngleIncrement*myPointCounter));
myY = myCenterPoint[1] + (myRadius * Math.sin(myAngleIncrement*myPointCounter));
myPathPoints.push([myX, myY]);
}
return myPathPoints;
}