Esta publicaci贸n es una continuaci贸n de la primera parte , donde se present贸 el script Expandir m谩scara de recorte y se describi贸 en detalle qu茅 y c贸mo lo hace, y en el camino se consideraron los principios b谩sicos de la creaci贸n de tales programas en general. En esta parte, continuar茅 la historia de c贸mo agregar nuevas funcionalidades al programa para obtener un "producto terminado" de la "pieza de trabajo". Aqu铆 no puede prescindir de una inmersi贸n m谩s profunda en el 谩rea tem谩tica, que es una de las condiciones necesarias para crear un producto completo. Entonces, comienza la inmersi贸n!
Las siguientes primitivas gr谩ficas se pueden usar como un contorno de m谩scara en Adobe Illustrator: un esquema simple (Ruta), un esquema compuesto (Ruta Compuesta), una forma compuesta (Forma Compuesta) y objetos de texto (Texto de Punto y Texto en la Ruta). Por el momento, el script solo funciona con contornos simples, como se puede ver en el siguiente c贸digo, donde PathItem
es una llamada al elemento Path.
var clipGroup = sel[0].pageItems.length; 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; }; };
Antes de eso, clipPath
la variable clipPath
, pero no le asignamos un valor.
var clipPath;
Esto significa que su valor a煤n no se ha determinado, es decir Es undefined
. Si ahora seleccionamos una m谩scara cuyo contorno ser谩, digamos, la ruta compuesta y ejecutamos el script, el programa producir谩 un error en la 煤ltima l铆nea de la parte funcional del script,
clipPath.remove();
clipPath
la condici贸n en el bucle no se cumplir谩, la variable clipPath
permanecer谩 undefined
y es imposible aplicar el m茅todo remove()
a algo indefinido. Para evitar esta situaci贸n, haremos lo siguiente: establecer clipPath
en null
, que, a diferencia de undefined
, ya es algo m谩s espec铆fico que al menos puede verificar.
Pensemos c贸mo determinar si alg煤n camino compuesto es el contorno de nuestra m谩scara. Cuando digo "pensemos", significa que sugiero buscar en la documentaci贸n y encontrar la propiedad que necesitamos. Por analog铆a con PathItem
estamos buscando la propiedad de clipping
. Resulta que el objeto CompoundPathItem
no tiene dicha propiedad, pero hay una propiedad pathItems
trav茅s de la cual puede obtener contornos PathItem
simples que tienen la propiedad de clipping
.
Ahora podemos convertir nuestros pensamientos / b煤squedas en c贸digo. En primer lugar, clipPath
que clipPath
no se defini贸 en la iteraci贸n anterior, y luego copiamos el bloque de c贸digo ya escrito y le hacemos peque帽os cambios.
if (clipPath == null) { var clipGroup = sel[0].pageItems.length; for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; };
En realidad, los cambios afectar谩n solo una l铆nea. Como podemos ver aqu铆, 'PathItem' ha cambiado a 'CompoundPathItem', y se ha agregado una nueva construcci贸n, 'pathItems [0]', con la que nos referimos al elemento de ruta compuesto.
if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) {
El siguiente es el bloque funcional de c贸digo que se ha creado hasta ahora.
var clipGroup = sel[0].pageItems.length; 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; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; };
El siguiente "paciente" es la forma compuesta. 隆Aqu铆 se vuelve bastante interesante! En la documentaci贸n no encontramos tal objeto en absoluto. Que hacer Primero, definamos a qu茅 clase de objetos pertenece. Para averiguarlo, escribiremos un peque帽o c贸digo auxiliar, que luego tiraremos. Como se mencion贸 en la primera parte , no abordamos el problema de las herramientas utilizadas para escribir / depurar c贸digo. Por lo tanto, suponga que este es un archivo separado, que luego simplemente va a la papelera. El c贸digo ser谩 el siguiente:
var obj = app.activeDocument.selection[0]; alert(obj.typename);
En la primera l铆nea, creamos un enlace al objeto seleccionado, en la segunda, mostramos un mensaje acerca de qu茅 tipo es. Seleccione el contorno de la m谩scara en Adobe Illustrator, es decir. el mismo objeto de Forma compuesta y ejecute el script. En el cuadro de mensaje, vemos que la Forma compuesta es un elemento de complemento. Nos deshacemos del c贸digo auxiliar, volvemos a la documentaci贸n nuevamente, pero no encontramos la propiedad de recorte o pathItems en PluginItem. En general, nada que nos ayude a indicar inequ铆vocamente que este objeto es el contorno de la m谩scara. A partir del script, ni siquiera puede determinar qu茅 tipo de complemento es. Alg煤n m贸dulo externo y eso es todo!
Eso es una emboscada! - exclamas en tus corazones. Y el cerebro est谩 trabajando febrilmente, con la esperanza de resolver un problema sin soluci贸n. Y luego, despu茅s de pasar por todas las opciones posibles e imposibles, presiona desesperadamente Del
y elimina la odiada Forma compuesta. Y aqu铆, por el rabillo del ojo en la paleta Layers
, notas que despu茅s de esta acci贸n, el contenedor de m谩scara, que era Clip Group
, se convirti贸 en solo Group
. 驴Qu茅 podr铆a significar? Y el hecho de que la propiedad clipped
del objeto clipped
de true
volvi贸 false
. 隆Aqu铆 est谩, una soluci贸n que podr铆a funcionar! Por supuesto, esto es, en general, un truco, pero qu茅 diferencia hace si ayuda a determinar el circuito deseado.
El algoritmo para determinar el contorno de la m谩scara representado por el objeto de Forma compuesta ser谩 el siguiente: iterar sobre todos los objetos de m谩scara en el bucle y cuando encontremos PluginItem, elim铆nelo y verifique si la propiedad clipped
del contenedor de m谩scara ha cambiado. Si se volvi贸 false
, entonces este es nuestro circuito. Lo 煤nico que funciona para este truco es actualizar DOM Illustrator despu茅s de eliminar el objeto, lo que se puede hacer usando el m茅todo app.redraw()
. Entonces a煤n debe recordar devolver el objeto remoto, que se realiza mediante el m茅todo app.undo()
.
A continuaci贸n se muestra el c贸digo para la ruta de Forma compuesta:
if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PluginItem') { sel[0].pageItems[i].remove(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; };
Ahora, de todas las opciones posibles para el tipo de objetos que pueden ser el contorno de la m谩scara, solo queda el texto (o TextFrameItem
, en la terminolog铆a de las referencias de script de ilustrador ). Pasamos a la documentaci贸n una y otra vez, no encontramos las propiedades de clipping
all铆. Pero esta vez, ya no nos preocupamos tanto por esto y tranquilamente descubrimos que TextFrameItem
tiene una propiedad kind
que determina el tipo de objeto de texto ( TextType
). Descubrimos que puede haber tres tipos: AREATEXT, POINTTEXT y PATHTEXT. El primer tipo no es interesante para nosotros, ya que no se puede usar como un esquema de m谩scara, y los otros dos siguen siendo tan interesantes. Solo queda encontrar un truco que nos ayudar谩 a determinar ahora no el contorno, sino el objeto de texto, que es el contorno de la m谩scara. Y ese truco ser谩 el equipo, Convertir a tipo de 谩rea, que convertir谩 POINTTEXT a AREATEXT. Al igual que con la Forma compuesta, se clipped
un cambio impl铆cito en la propiedad clipped
.
En consecuencia, el c贸digo para un TextFrameItem de tipo POINTTEXT ser谩 el siguiente:
if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.POINTTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; };
Solo queda un TextFrameItem
tipo PATHTEXT. Desafortunadamente, al convertir PATHTEXT a AREATEXT, la propiedad clipped
no cambia. Pero como este es el 煤ltimo candidato posible para el t铆tulo "esquema de m谩scara", es posible utilizar tal comportamiento. Es decir, verificamos que despu茅s de ejecutar el clipped
Convert To Area Type
, la propiedad clipped
sigue siendo true
. A continuaci贸n se muestra el c贸digo para un TextFrameItem de tipo PATHTEXT.
if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.PATHTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == true) { clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; };
Por lo tanto, si reunimos piezas de c贸digo escritas secuencialmente, incluido un bloque de cheques, obtendremos dicho c贸digo, cuya ejecuci贸n, como se indica en la primera parte de la publicaci贸n, implementar谩 la acci贸n del nuevo comando Expandir m谩scara de recorte en Adobe Illustrator.
#target illustrator if (app.documents.length > 0) { var doc = app.activeDocument; var sel = doc.selection; var clipPath = null; if (sel.length > 0) { if (sel[0].typename == 'GroupItem' && sel[0].clipped == true) { var clipGroup = sel[0].pageItems.length; 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; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PluginItem') { sel[0].pageItems[i].remove(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.POINTTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.PATHTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == true) { clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; }; app.executeMenuCommand('releaseMask'); clipPath.remove(); } else { alert (' -!'); }; } else { alert (' !'); }; } else { alert (' !'); };
Aqu铆 puedes poner fin a. No, un punto y coma es mejor.
Espero que con estas publicaciones te ayude a acercarte un poco m谩s a tu objetivo: comenzar a programar en Adobe Illustrator. Gracias por su atencion!