Ich möchte Sie sofort warnen, dass diese Reihe von Beiträgen nicht für erfahrene Programmierer oder überhaupt nicht für Programmierer gedacht ist. Ich verstehe, dass dies angesichts des IT-Themas der Ressource äußerst trotzig klingt, und lasse mich dennoch erklären ... Als Publikum sehe ich gewöhnliche Designer, die mit dem Programmieren in Adobe beginnen möchten, aber aus irgendeinem Grund (aus Angst vor unbekannt, mangelndes Vertrauen in ihre Fähigkeiten oder mangelnde Sprachkenntnisse) können nicht die ersten Schritte in diese Richtung unternehmen. Ich sehe meine bescheidene Aufgabe darin, ihnen zu helfen, zu verstehen, dass "nicht die Götter die Töpfe verbrennen" und jede ausreichend motivierte Person lernen kann, Arbeitsprogrammcode zu schreiben. Es ist möglich, dass einige von ihnen von diesem Spiel so mitgerissen werden, dass sie sich entscheiden, echte Entwickler zu werden. Welcher Code scherzt nicht?
In diesem Beitrag erfahren Sie, wie Sie Ihr eigenes kleines Tool (Skript in JavaScript) schreiben, um Ihr eigenes einzigartiges Tool in Adobe Illustrator zu erstellen. Dies reduziert nicht nur Ihre Zeit, sondern verbessert auch die Interaktion mit diesem wunderbaren Grafikeditor. Zuerst werde ich das Problem formulieren, dann werde ich den Code zeigen, der es löst, und dann werde ich Ihnen detailliert erklären, wie es erstellt wurde. Die Grundlagen von Javascript, die Funktionen des Illustrator-Objektmodells oder verschiedene Editoren zum Schreiben / Debuggen von Code werden nicht behandelt. Sie können diese Informationen selbst finden, wenn Sie dies wünschen. Die Hauptsache ist meiner Meinung nach ein Verständnis der Grundprinzipien des Schreibens von Programmen, das den Schwerpunkt dieses Artikels bildet. Wenn Sie bereit sind, direkt über Ihren Kopf zu springen, begrüßen Sie den Schnitt!
Adobe Illustrator verfügt über ein Schnittmaskenwerkzeug, das mit Schnittmasken funktioniert. Die Schnittmaske enthält drei Befehle: Make, Release und Edit Mask. Der erste erstellt eine Maske, der zweite - analysiert, der dritte - ermöglicht das Bearbeiten. Wir interessieren uns für den zweiten Befehl, der das Schnittmaskenobjekt in eine Kontur und den Inhalt der Maske aufteilt. Sehr oft ist es notwendig, nicht nur die Maske zu zerlegen, sondern auch den Umriss der Maske zu entfernen, wobei nur der Inhalt übrig bleibt. Der reguläre Befehl "Schnittmaske freigeben" führt dies nicht aus. Nach dem Anwenden müssen Sie drei weitere Schritte ausführen:
- Auswahl aus Objekten entfernen
- Nur Maskenumriss auswählen
- Maskenumriss entfernen
Wenn Sie diese sequentielle Operation tagsüber ziemlich oft ausführen müssen, stellt sich die Frage: Ist es unmöglich, die Anzahl dieser Aktionen irgendwie zu reduzieren, um das gleiche Ergebnis zu erzielen? Und hier geht es überhaupt nicht um Faulheit, sondern um das Fehlen des notwendigen Werkzeugs. Stellen Sie sich jetzt für eine Sekunde vor, Sie hätten ein solches Werkzeug.
Hier werden Sie kurz von der Arbeit abgelenkt und in Gedanken darüber versetzt, wie cool es wäre, wenn ein Team im Arsenal von Adobe Illustrator wie die Expand Clipping Mask all diese Aktionen für Sie ausführen würde. Coole Idee! Sie müssen technischen Support für Adobe schreiben, denken Sie. Der folgende Gedanke: Plötzlich wurden sie schon oft darüber geschrieben? Und wenn sie eines Tages und vielleicht ein solches Tool hinzufügen, was ist das für Sie? Dieses Team wird hier und jetzt gebraucht!
Und hier kommt der Moment der Wahrheit - Sie können selbst ein Drehbuch schreiben!
Kaum gesagt als getan!
1 #target illustrator 2 if (app.documents.length > 0) { 3 var doc = app.activeDocument; 4 var sel = doc.selection; 5 var clipPath; 6 if (sel.length > 0) { 7 if (sel[0].typename == 'GroupItem' && sel[0].clipped == true) { 8 var clipGroup = sel[0].pageItems.length; 9 for (var i = 0; i < clipGroup; i++) { 10 if (sel[0].pageItems[i].typename == 'PathItem' && sel[0].pageItems[i].clipping == true) { 11 clipPath = sel[0].pageItems[i]; 12 break; 13 }; 14 }; 15 app.executeMenuCommand('releaseMask'); 16 clipPath.remove(); 17 } 18 else { 19 alert (' -!'); 20 }; 21 } 22 else { 23 alert (' !'); 24 }; 25 } 26 else { 27 alert (' !'); 28 };
Hier ist ein so kleiner Code, um dieses Problem zu lösen. Anstelle mehrerer, bereits in der Reihenfolge langweiliger Aktionen, müssen Sie nur eines tun - das Skript "Schnittmaske erweitern" ausführen. Jetzt haben Sie ein praktisches Werkzeug zum Arbeiten mit Masken, das von demselben Heimwerker erstellt wurde.
Natürlich bin ich hier etwas unaufrichtig. Erstens wurde das Skript nicht von Ihnen geschrieben, und zweitens ist es nicht so universell, wie wir es gerne hätten. Wenn Sie jedoch daran interessiert sind, wie es funktioniert und vor allem, wie Sie lernen, wie man solche Programme selbst schreibt, dann werde ich Ihnen dies gerne in der richtigen Reihenfolge und mit detaillierten Kommentaren mitteilen.
Zunächst besteht jedes Skript (Skript / Programm / JavaScript-Code) aus mehreren Hauptcodeblöcken: Deklarationen (Initialisierung) von Variablen, grundlegende Überprüfungen (Bedingungen) und beispielsweise die „Programm-Engine“ - Code, der die Hauptarbeitsfunktion implementiert Skript. Natürlich ist diese Aufteilung sehr willkürlich, da der Funktionsteil auch Kontrollen aufweist, aber das strukturelle Prinzip ist dies. Je größer das Programm ist, desto schwieriger wird es natürlich, es in ähnliche Blöcke zu unterteilen. Aber in unserem Fall ist es möglich. Die Zeilen 8 bis 16 sind die Skript-Engine, die verbleibenden Zeilen sind Variablendeklarationen und verschiedene grundlegende Überprüfungen bei ihrer Verarbeitung. Wenn Sie zählen, stellt sich heraus, dass die Anzahl der Zeilen im Prüfblock größer ist als die Anzahl der Zeilen im Funktionsblock. Sind diese Überprüfungen wirklich wichtig?
Warum brauchen wir Schecks?
Seriöse Programmierer werden mich verstehen und es wird für Anfänger nützlich sein, sich darüber zu informieren. Es sind Überprüfungen erforderlich, um das normale Funktionieren des Funktionsteils des Programms sicherzustellen. Wenn Sie sie nicht schreiben, führt jeder Fehler während der Ausführung des Skripts zu einem Softwarefehler. Und das ist nicht gut.
Natürlich verwenden die oben erwähnten ernsthaften Kameraden das Try / Catch-Konstrukt für solche Zwecke, aber ich entschied, dass das übliche if / else ein lakonisches und verständlicheres Konstrukt wäre. Besonders für unerfahrene Drehbuchautoren.
Lassen Sie uns im Detail untersuchen, was diese Zeilen tun. Die erste Zeile ist dafür verantwortlich, dass das Skript auch dann ausgeführt wird, wenn es nicht in Adobe Illustrator ausgeführt wird. Wenn Sie das Skript in Illustrator ausführen, kann diese Zeile daher weggelassen werden.
#target illustrator
Anschließend wird zum Zeitpunkt der Skriptausführung in Adobe Illustrator nach offenen Dokumenten gesucht. Diese Zeilen sollten wie folgt gelesen werden: Wenn ( if
) in der Anwendung ( app
) die Anzahl der Dokumente ( documents.length
) größer als Null (> 0) ist, sollte der in {...} enthaltene Code ausgeführt werden. Andernfalls ( else
) wird die Meldung ( alert
) "Keine offenen Dokumente!" Angezeigt. und vervollständigen Sie das Skript.
if (app.documents.length > 0) { ... ... } else { alert (' !'); };
Der folgende Codeblock prüft die Auswahl im Dokument.
if (sel.length > 0) { ... ... } else { alert (' !'); };
Es sollte beachtet werden, dass wenn wir in den vorherigen Beispielen reservierte Namen (wie app
oder documents
) verwendet haben, wir hier die sel-Variable verwenden, die wir selbst in den Zeilen 3 und 4 bestimmt haben.
var doc = app.activeDocument; var sel = doc.selection;
Dabei ist doc
die Verknüpfung zum aktiven Illustrator-Dokument und sel
die Verknüpfung zu dem ausgewählten Objekt / den ausgewählten Objekten im aktiven Dokument.
Eine Referenz (oder Referenz) ist ein Zeiger auf ein bestimmtes Objekt. Natürlich ist mir klar, dass das völlig harmlose russische Wort "Zeiger" jede Person in den Stupor einführen kann, die mit OOP (objektorientierte Programmierung) nicht vertraut ist. Aber nehmen Sie ein Wort, alles ist nicht so kompliziert, wie es scheint. Links werden in Variablen gespeichert und für den Zugriff auf Objekte verwendet. In der doc
Variablen speichern wir einen Zeiger auf das aktive Dokument (activeDocument) der Anwendung (App) (weisen ihm mit dem Zuweisungsoperator =
einen Wert zu) und in der sel
Variablen speichern wir den Zeiger auf die Auswahl (Auswahl) im aktiven Dokument (activeDocument) der Anwendung (App). Um zu vermeiden, dass app.activeDocument erneut geschrieben wird, verwenden wir stattdessen die Variable doc
, die diesen Code bereits enthält. Deshalb sieht der Link wie folgt aus: sel = doc.selection
. Ich hoffe ich habe es klar erklärt.
Wenn in diesem Zustand if (sel.length > 0)
geprüft wird, ob das aktive Dokument ausgewählte Objekte enthält, wird die Meldung angezeigt: 'Keine ausgewählten Objekte!'
Die folgenden Zeilen überprüfen die Richtigkeit, entschuldigen Sie das Wortspiel, zwei Bedingungen gleichzeitig. Das erste, dass das ausgewählte Objekt eine Gruppe ist ( GroupItem
) und (&&) das zweite, dass diese Gruppe wirklich eine GroupItem
ist (die clipped
Eigenschaft dieses Objekts ist true
).
if (sel[0].typename == 'GroupItem' && sel[0].clipped == true) { ... ... } else { alert (' -!'); };
Hier brauchen wir eine kleine Erklärung.
Was ist ein Maskenobjekt? Dies ist eine Gruppe, aber keine gewöhnliche. Eine reguläre Gruppe ist eine Sammlung verschiedener Objekte, die beispielsweise dem Haupt- oder Elternobjekt untergeordnet sind. Das Maskenobjekt ist ebenfalls eine Gruppe, besteht jedoch im Gegensatz zum üblichen aus zwei Teilen - dem Umriss der Maske und ihrem Inhalt. Um anhand des Skripts festzustellen, ob es sich vor Ihnen um eine reguläre Gruppe oder eine Maskengruppe handelt, können Sie dies anhand der clipped
Eigenschaft tun. Wenn der Wert der abgeschnittenen Eigenschaft false
(false) ist, handelt es sich um eine normale Gruppe. Wenn true
(true), handelt es sich um eine Clipping-Gruppe.
Anfragende Köpfe werden feststellen, dass anstelle der zuvor definierten sel
Variablen das sel[0]
-Konstrukt verwendet wird. Dies wird durch die Tatsache erklärt, dass eine Auswahl aus Sicht des Skripts eine Sammlung (Sammlung) von Elementen und kein bestimmtes Objekt ist (selbst wenn nur ein Objekt ausgewählt ist). typename
den Typ ( typename
) dieses Objekts auf Übereinstimmung mit dem Typ des ausgewählten Auflistungselements zu überprüfen, wird das Konstrukt sel[0]
verwendet, das sich auf das erste [0]
-Element der Auflistung bezieht, typename
in unserem Fall auf die ausgewählte Gruppe.
Wenn das ausgewählte Objekt sowohl eine Gruppe als auch eine Maske ist, wird der weitere Code ausgeführt, andernfalls wird die Meldung angezeigt: "Auswahl ist kein Maskenobjekt!"
Mit Schecks - das war's. Mach weiter.
Wie wurde der Hauptcode erstellt?
In diesem Teil des Artikels werde ich versuchen, nicht nur die Funktionsweise des Codes zu kommentieren, sondern auch den Prozess seiner Erstellung zu beschreiben. Wenn nicht der gesamte Prozess, dann zumindest einige wichtige Punkte. Fangen wir an!
Zuvor wurden drei Aktionen beschrieben, die ausgeführt werden müssen, um die Aufgabe des „Zerlegens“ der Schnittmaske mit dem anschließenden Entfernen des Maskenumrisses zu lösen. Sie werden durch eine weitere Aktion (Freigabebefehl) ergänzt, von der aus unser Algorithmus beginnt. Ich werde sie hier wiederholen, um den Kontext zu aktualisieren.
- Führen Sie den Befehl Release Clipping Mask aus
- Auswahl aus Objekten entfernen
- Nur Maskenumriss auswählen
- Maskenumriss entfernen
Wenn Sie diese Abfolge von Aktionen streng nach der Liste implementieren, können die ersten beiden Punkte einfach durch Aufrufen der Methode executeMenuCommand()
gelöst werden. Aber dann, am dritten Punkt, werden wir vor einem unlösbaren Problem stehen. Wie erhalte ich einen Link zum Maskenumriss, wenn nach der ersten Aktion (Schnittmaske freigeben) keine Maske mehr vorhanden ist, sondern nur noch eine Reihe ausgewählter Objekte? Ja, und er ist strukturell nicht derselbe wie vor der Durchführung dieser Operation.
Im Allgemeinen schlägt die Logik vor, dass Sie zuerst einen Link (Verweis) zum Maskenumrissobjekt erstellen müssen. Nachdem wir uns überlegt haben, was PathItem
Maskenkontur im Vergleich zur regulären Kontur so einzigartig PathItem
, finden wir die clipping
Eigenschaft der PathItem
Klasse. Jetzt müssen wir nur noch die Objekte der Maskengruppe in der (for) -Schleife PathItem
und das PathItem
mit der Eigenschaft clipping = true
. Dies ist die gewünschte Schaltung. Als Ergebnis der Ausführung dieses Codes erhalten wir einen Link zum Maskenkonturobjekt und speichern ihn in der Variablen clipPath
.
for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PathItem' && sel[0].pageItems[i].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; };
Was weiter? Kehren wir zum Algorithmus zurück und schreiben den Code für Element 1. In dieser Zeile wird der Befehl "Clipping Mask freigeben" ausgeführt, jedoch nicht über die Benutzeroberfläche, sondern über das Skript. Ja so einfach!
app.executeMenuCommand('releaseMask');
Wir überspringen die Schritte 2 und 3 (da wir bereits einen Maskenumriss oder vielmehr einen Link zum clipPath-Objekt haben) und fahren direkt mit Schritt 4 fort. Hier rufen wir die remove()
-Methode des clipPath
Objekts auf. Diese Methode entfernt den Umriss der Maske.
clipPath.remove();
Das ist alles für jetzt. Vielen Dank für Ihre Aufmerksamkeit!
Ich hoffe, Sie verstehen jetzt, dass das Programmieren in Adobe Illustrator nicht so schwierig ist, wie es auf den ersten Blick scheint.
PS: Das resultierende Skript ist natürlich alles andere als ideal. Es funktioniert nicht mit Masken, deren Umrisse durch CompoundPath
, CompoundShape
oder TextFrame
. Lesen Sie im zweiten Teil, wie Sie das Skript so ändern, dass es zu einem wirklich vollwertigen Werkzeug wird.