() translation by (you can also view the original English article)
En esta introducción al lenguaje de secuencias de comandos de JavaScript para Flash (JSFL), aprenderás a automatizar tareas repetitivas y a añadir nuevos comandos al entorno de creación de Flash.
Introducción
Comenzaremos explorando JSFL en general, viendo lo que puede hacer, para luego llegar a una aplicación útil de la misma: un comando que puede convertir un texto en un botón (con su área de golpeo establecida correctamente) en un solo clic.





Paso 1: Crear un archivo JSFL
Abre Flash y haz clic en Archivo > Nuevo. Selecciona Archivo JavaScript de Flash de la lista, y guarda tu nuevo documento como example.jsfl, donde quieras.
JSFL es un formato de texto plano, por lo que puede abrir los archivos JSFL en cualquier editor de texto.
Paso 2: Crear un FLA
Necesitaremos un FLA en blanco para probar nuestros scripts, así que crea uno de estos también. Ni siquiera tienes que guardarlo; es solo para probar.
Paso 3: Escribir un script
En tu archivo JSFL, pega el siguiente código:
1 |
fl.getDocumentDOM().addNewOval({left:100, top:150, right:150, bottom:200}); |
Incluso si nunca has utilizado JavaScript, la sintaxis es lo suficientemente similar a la de ActionScript como para que puedas adivinar lo que hace:
- fl es un objeto que representa la propia aplicación Flash
- getDocumentDOM() devuelve el FLA actualmente abierto
- addNewOval() dibuja un óvalo en el FLA, con los parámetros dados
Paso 4: Ejecutar el script
Si estás editando el JSFL en Flash, ejecuta el script haciendo clic en el gran botón triangular de reproducción de la barra de herramientas. Si no, haz doble clic en el archivo JSFL en tu ordenador y se ejecutará automáticamente en Flash.
Deberías ver aparecer un círculo, utilizando los colores que habías seleccionado. Muy bien. Ahora cada vez que necesites dibujar un círculo de 50px centrado en (125, 125), no tendrás que dibujarlo.
Paso 5: Hacer el script más codicioso
Sin embargo, este es un resultado algo aburrido. Hagamos las cosas más complejas:
1 |
for (i=0; i<8; i++) |
2 |
{
|
3 |
fl.getDocumentDOM().addNewOval({left:(i*50), top:(i*50), right:(i*50)+50, bottom:(i*50)+50}); |
4 |
}
|
Sí, JavaScript también tiene bucles for. Esta vez, ejecuta el JSFL cambiando a tu FLA, haciendo clic en Comandos > Ejecutar Comando, y luego buscando tu archivo de script en tu disco duro.
Comprueba el resultado:



Ya está claro que esto puede ser muy útil para encargarse de tareas repetitivas y precisas. Por ejemplo, sería fácil modificar ese código para crear una cuadrícula de círculos... y de ahí a crear una cuadrícula de botones hay un pequeño paso. Ya no es necesario copiar, pegar y desplazar suavemente los símbolos por el escenario para alinearlos correctamente.
Paso 6: Trazar
Siempre es bueno tener un comando trace() disponible cuando se está probando algo nuevo. En JSFL, tenemos la función fl.trace(), que toma una sola cadena (a diferencia de la función trace() de AS3, que puede tomar varias a la vez) y la imprime en el panel de salida. Pruébalo:
1 |
for ( var i = 0; i < 8; i++ ) { |
2 |
fl.getDocumentDOM().addNewOval({left:(i*50), top:(i*50), right:(i*50)+50, bottom:(i*50)+50}); |
3 |
fl.trace( "i is: " + i.toString() ); |
4 |
}
|
El resultado:
1 |
i is: 0 |
2 |
i is: 1 |
3 |
i is: 2 |
4 |
i is: 3 |
5 |
i is: 4 |
6 |
i is: 5 |
7 |
i is: 6 |
8 |
i is: 7 |
Paso 7: Añadir el comando al menú
Tener que mantener el JSFL abierto o navegar hasta él cada vez que quieras usarlo sería un verdadero dolor. En su lugar, puedes añadirlo al menú de comandos para que esté a un par de clics de distancia. (Y una vez que esté ahí, incluso puedes asignarle un atajo de teclado).
Todo lo que tienes que hacer es mover tu archivo example.jsfl a la carpeta \Command\ de Flash. Sin embargo, la ubicación de esta carpeta depende de tu sistema operativo:
- Mac OS X: [hard drive]/Users/userName/Library/Application Support/Adobe/Flash CS3/language/Configuration/Commands
- Windows XP: [boot drive]\Documents and Settings\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands
- Windows Vista: [boot drive]\Users\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands
- Windows Vista (alt): [boot drive]\Users\username\AppData\Local\Adobe\Flash CS3\language\Configuration\Commands
- Windows 7: [boot drive]\Users\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands
- Windows 7 (alt): [boot drive]\Users\username\AppData\Local\Adobe\Flash CS3\language\Configuration\Commands
La carpeta username coincidirá con el nombre que utilices para iniciar la sesión, el idioma cambiará dependiendo de lo que hayas elegido cuando instalaste Flash (para los hispanohablantes probablemente será en-us o simplemente en), y si estás utilizando una versión de Flash más reciente que CS3, esa carpeta también cambiará.
Una vez guardado en esa carpeta, aparecerá en el menú de comandos, utilizando el nombre del archivo JSFL:

Solo tienes que hacer clic para ejecutarlo. Ahora puedes editar el archivo JSFL dentro de la carpeta Commands, para acelerar las cosas.
Paso 8: Recuperar información del FLA
JSFL puede hacer más que ejecutar listas de comandos. También puede obtener información sobre el FLA y los elementos que contiene, y tomar decisiones basadas en esa información.
Por ejemplo, podríamos escribir un script para rastrear cuántos elementos están actualmente seleccionados:
1 |
fl.trace( fl.getDocumentDOM().selection.length ) |
El objeto selection es en realidad un array, en el que cada elemento contiene uno de los objetos seleccionados. Por eso selection.length nos da el número de objetos seleccionados.
Este sencillo script da una idea de cómo funciona Flash: prueba a dibujar unos cuantos círculos, seleccionarlos todos y ejecutar el script. Devolverá "1". Crea unos cuantos campos de texto, selecciónalos todos y ejecuta el script, y devolverá un número igual al número de campos de texto.
Paso 9: Encontrar el tipo de un objeto
También podemos obtener información sobre los objetos dentro de esa selección:
1 |
for ( var i = 0; i < fl.getDocumentDOM().selection.length; i++ ) |
2 |
{
|
3 |
fl.trace( fl.getDocumentDOM().selection[i].elementType ); |
4 |
}
|
Tengo dos campos de texto y un montón de círculos seleccionados, y esta secuencia de comandos scripts:
1 |
text
|
2 |
text
|
3 |
shape
|
Para obtener una lista completa de objetos y funciones, explora el libro Extending Flash en Adobe LiveDocs.
Paso 10: Modificar objetos en el escenario
Aquí hay un simple script que aplasta todas las formas seleccionadas en el escenario, pero nada más:
1 |
for ( var i=0; i < fl.getDocumentDOM().selection.length; i++ ) |
2 |
{
|
3 |
if ( fl.getDocumentDOM().selection[i].elementType == "shape" ) |
4 |
{
|
5 |
fl.getDocumentDOM().selection[i].scaleY = 2; |
6 |
}
|
7 |
}
|
Antes:



...y después:



Paso 11: "Abotonarse" Resumen
Ya tienes lo básico. Ahora es el momento de la carne de este tutorial.
Vamos a crear un script que toma un campo de texto y lo convierte en un botón. Voy a caminar a través de los pasos que este script va a replicar; iniciar un nuevo FLA y poner un campo de texto en el medio, a continuación, sigue adelante:
- Haz clic en el texto
- Convertirlo en un símbolo
- Ir al modo de edición
- Crear nuevos fotogramas clave: encima, abajo, golpe
- Dibuja un rectángulo sólido que cubra el texto para definir el área de impacto. Publicar traducción
Es bastante sencillo, cuando lo ves enumerado así. ¿Pero cómo hacemos todo eso en JSFL? ¿Cuál es el script?
Podríamos buscar todo en los LiveDocs, pero hay una manera mucho más fácil...
Paso 12: El panel histórico
Haz clic en Ventana > Otros paneles > Historial para que aparezca el panel Historial:

Esos son todos los pasos que necesitamos. Si solo estuvieran en la JSFL...
Paso 13: La lista del panel histórico en JSFL
Ah, sí, están en JSFL. Haz clic en este pequeño botón:

...y luego haz clic en Ver > JavaScript en el Panel:



Resultado:



No es exactamente lo que necesitamos, pero nos da alguna indicación de dónde buscar en los LiveDocs.
Paso 14: Copiar el historial
Haz clic en el elemento superior del historial que necesites y pulsa la tecla Mayúsculas y haz clic en la parte inferior para seleccionar todos los pasos intermedios. Puedes hacer ctrl-clic (cmd-clic en Mac) en elementos individuales para deseleccionarlos de esta lista (yo he eliminado algunos clics innecesarios del mío). Luego, haz clic de nuevo en ese pequeño botón del menú y selecciona Copiar Pasos. Ahora puedes pegarlos en un archivo JSFL:
1 |
fl.getDocumentDOM().convertToSymbol('button', '', 'top left'); |
2 |
var lib = fl.getDocumentDOM().library; |
3 |
if (lib.getItemProperty('linkageImportForRS') == true) { |
4 |
lib.setItemProperty('linkageImportForRS', false); |
5 |
}
|
6 |
else { |
7 |
lib.setItemProperty('linkageExportForAS', false); |
8 |
lib.setItemProperty('linkageExportForRS', false); |
9 |
}
|
10 |
lib.setItemProperty('scalingGrid', false); |
11 |
|
12 |
fl.getDocumentDOM().enterEditMode('inPlace'); |
13 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
14 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
15 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
16 |
fl.getDocumentDOM().addNewRectangle({left:125.0, top:133, right:344.9, bottom:207}, 0); |
Guarda esto como Buttonize.jsfl.
(Como alternativa, puedes hacer clic en el botón Guardar para crear un archivo JSFL en el directorio Comandos, en cuyo caso el script tendrá comentarios para ayudar a explicar cada paso).
Paso 15: Script de prueba
Vamos a probar el script tal y como está ahora mismo para hacernos una idea de lo que tenemos que mejorar. Inicia otro FLA en blanco, crea un campo de texto (ponlo en una posición diferente, con un texto diferente), haz clic en él y ejecuta el JSFL.
¿Funcionó? El mío no fue un éxito:

Podemos ver que tendremos que mover la caja para que su tamaño y posición coincidan con los del campo de texto.
Paso 16: Obtener las dimensiones del campo de texto
Afortunadamente, ya sabemos cómo obtener información sobre un elemento seleccionado. Podemos adivinar cómo se llamarán las propiedades de dimensión del objeto seleccionado; intentemos trazarlas y ver si estamos en lo cierto:
1 |
fl.trace( fl.getDocumentDOM().selection[0].x ); |
2 |
fl.trace( fl.getDocumentDOM().selection[0].y ); |
3 |
fl.trace( fl.getDocumentDOM().selection[0].width ); |
4 |
fl.trace( fl.getDocumentDOM().selection[0].height ); |
Sorpresa, sorpresa, sí, eso funciona bien. Ahora podemos usar esa información para dibujar el rectángulo:
1 |
fl.getDocumentDOM().addNewRectangle({left:fl.getDocumentDOM().selection[0].x, top:fl.getDocumentDOM().selection[0].y, right:fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width, bottom:fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height}, 0); |
Pruébalo:



...Oh.
Paso 17: Almacenar la información antes de los cambios de selección
¿Qué ha pasado? Bueno, cuando el script entró en el modo Edición, la selección cambió; estamos dentro del símbolo del Botón, así que ya no lo tenemos seleccionado. Ten cuidado con este tipo de errores cuando trabajes con JSFL.
Sin embargo, esto es fácil de arreglar: solo tenemos que almacenar las propiedades de la izquierda, la parte superior, la derecha y la parte inferior antes de que cambie la selección:
1 |
var textLeft = fl.getDocumentDOM().selection[0].x; |
2 |
var textTop = fl.getDocumentDOM().selection[0].y; |
3 |
var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width; |
4 |
var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height; |
5 |
|
6 |
fl.getDocumentDOM().convertToSymbol('button', '', 'top left'); |
7 |
var lib = fl.getDocumentDOM().library; |
8 |
if (lib.getItemProperty('linkageImportForRS') == true) { |
9 |
lib.setItemProperty('linkageImportForRS', false); |
10 |
}
|
11 |
else { |
12 |
lib.setItemProperty('linkageExportForAS', false); |
13 |
lib.setItemProperty('linkageExportForRS', false); |
14 |
}
|
15 |
lib.setItemProperty('scalingGrid', false); |
16 |
|
17 |
fl.getDocumentDOM().enterEditMode('inPlace'); |
18 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
19 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
20 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
21 |
fl.getDocumentDOM().addNewRectangle({left:textLeft, top:textTop, right:textRight, bottom:textBottom}, 0); |
¿Funcionó? A mí me funcionó.
Paso 18: Comprobar los posibles errores
¿Qué ocurre si ejecutamos el comando sin seleccionar el texto? Obtenemos el mismo error que antes:



Deberíamos comprobar si hay algún objeto seleccionado antes de hacer nada:
1 |
if ( fl.getDocumentDOM().selection.length > 0 ) |
2 |
{
|
3 |
var textLeft = fl.getDocumentDOM().selection[0].x; |
4 |
var textTop = fl.getDocumentDOM().selection[0].y; |
5 |
var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width; |
6 |
var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height; |
7 |
|
8 |
fl.getDocumentDOM().convertToSymbol('button', '', 'top left'); |
9 |
var lib = fl.getDocumentDOM().library; |
10 |
if (lib.getItemProperty('linkageImportForRS') == true) { |
11 |
lib.setItemProperty('linkageImportForRS', false); |
12 |
}
|
13 |
else { |
14 |
lib.setItemProperty('linkageExportForAS', false); |
15 |
lib.setItemProperty('linkageExportForRS', false); |
16 |
}
|
17 |
lib.setItemProperty('scalingGrid', false); |
18 |
|
19 |
fl.getDocumentDOM().enterEditMode('inPlace'); |
20 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
21 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
22 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
23 |
fl.getDocumentDOM().addNewRectangle({left:textLeft, top:textTop, right:textRight, bottom:textBottom}, 0); |
24 |
}
|
En realidad, podemos hacerlo mejor... ¿qué tal si comprobamos si se ha seleccionado exactamente un campo de texto?
1 |
if ( fl.getDocumentDOM().selection.length == 1 ) |
2 |
{
|
3 |
if ( fl.getDocumentDOM().selection[0].elementType == "text" ) |
4 |
{
|
5 |
var textLeft = fl.getDocumentDOM().selection[0].x; |
6 |
var textTop = fl.getDocumentDOM().selection[0].y; |
7 |
var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width; |
8 |
var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height; |
9 |
|
10 |
fl.getDocumentDOM().convertToSymbol('button', '', 'top left'); |
11 |
var lib = fl.getDocumentDOM().library; |
12 |
if (lib.getItemProperty('linkageImportForRS') == true) { |
13 |
lib.setItemProperty('linkageImportForRS', false); |
14 |
}
|
15 |
else { |
16 |
lib.setItemProperty('linkageExportForAS', false); |
17 |
lib.setItemProperty('linkageExportForRS', false); |
18 |
}
|
19 |
lib.setItemProperty('scalingGrid', false); |
20 |
|
21 |
fl.getDocumentDOM().enterEditMode('inPlace'); |
22 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
23 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
24 |
fl.getDocumentDOM().getTimeline().convertToKeyframes(); |
25 |
fl.getDocumentDOM().addNewRectangle({left:textLeft, top:textTop, right:textRight, bottom:textBottom}, 0); |
26 |
}
|
27 |
}
|
Esto abre todo tipo de opciones. Si se seleccionan varios elementos, se puede hacer un bucle con todos ellos y convertirlos en botones. Si se selecciona un objeto que no es un campo de texto, podría tratarlo de forma diferente, quizás no necesitaría un rectángulo para su forma Hit.
Paso 19: Nombrar el botón según el texto
Un buen detalle sería dar al símbolo del botón el mismo nombre que el texto que contiene. Eso también mantendría la Biblioteca ordenada. Pero no hay nada en nuestro script que sugiera cómo podríamos hacerlo.
Sabemos que el JSFL para convertir una selección en un símbolo es fl.getDocumentDOM().convertToSymbol(), gracias al panel Historia. Si buscas eso en los LiveDocs, encontrarás que el segundo parámetro (que el script del panel Historia dejó en blanco) se llama name, y se describe así:
Una cadena que especifica el nombre del nuevo símbolo, que debe ser único. Puedes enviar una cadena vacía para que este método cree un nombre de símbolo único para ti.
¡Bingo! Por supuesto, no sabemos lo que dice el texto...
Paso 20: Obtener el texto
Podríamos tener una suposición:
1 |
fl.trace( fl.getDocumentDOM().selection[0].text ); |
Lamentablemente, esto devuelve sin definir. Ah, bueno.
No hay que preocuparse, un rápido vistazo a los LiveDocs revela esta página sobre el objeto Text. Allí podemos encontrar la función que estamos buscando: text.getTextString().
Añade eso a tu script:
1 |
var textLeft = fl.getDocumentDOM().selection[0].x; |
2 |
var textTop = fl.getDocumentDOM().selection[0].y; |
3 |
var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width; |
4 |
var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height; |
5 |
var textText = fl.getDocumentDOM().selection[0].getTextString(); |
6 |
|
7 |
fl.getDocumentDOM().convertToSymbol('button', textText, 'top left'); |
Pruébalo.

Fantástico.
Resumen
Buttonize es un pequeño comando muy útil si necesitas maquetar una interfaz de usuario rápidamente, pero no era el objetivo del tutorial. El objetivo era familiarizarse con JSFL, y ver dónde se podía utilizar. Espero que la próxima vez que te enfrentes a una hora de trabajo de tediosas tareas de Flash, descubras cómo automatizarlo con un script en la mitad de tiempo :)