> Manuales > Manual de Processing.js

Comunicar Processing y Javascript para poder ejecutar código Processing desde funciones creadas en Javascript.

En el Manual de Processing.js hemos explicado muchas de las cosas que podríamos necesitar al utilizar estas librerías para crear animaciones e interactividad en elementos Canvas del HTML5. Hemos visto que podemos controlar los elementos canvas por medio del lenguaje Processing, que tiene una sintaxis, así como un API de funciones, independiente de Javascript. Actualmente estamos trabajando para explicar las bases que nos ayuden a comunicar los scripts Javascript y los scripts Processing.

En el anterior artículo tratamos con detalle cómo desde el lenguaje Processing podemos invocar métodos Javascript y acceder a los objetos del navegador que están disponibles en el DOM de la página. Ahora vamos a hacer el paso contrario, es decir, desde scripts en Javascript acceder a métodos creados dentro de Processing.

Acceder a una copia de una instancia Processing

El paso de acceder desde Processing a variables, funciones y objetos Javascript es bien simple, ya que el propio lenguaje Processing se convierte en Javascript por medio de las librerías Processing.js. Pero para hacer el paso contrario la cosa no es tan directa.

Si queremos acceder a un objeto Processing asociado a un elemento canvas, de modo que podamos invocar métodos de él, tenemos que primero hacernos con una copia de la instancia Processing que se ha generado para trabajar con ese canvas. Para ello existe un método llamado getInstanceById(), que tendremos disponible una vez cargadas las librerías Processing.js y al que le tenemos que enviar el identificador del elemento canvas sobre el que queremos acceder a su objeto Processing.

Por ejemplo, tenemos este canvas:

<canvas id="canvasdesarrolloweb" data-processing-sources="archivo-processing.pjs"></canvas>

Como vemos, el elemento canvas tiene asociado un código Processing.js (definido en archivo-processing.pjs) que es el encargado de generar el dibujo y la animación sobre el lienzo. Al definir ese atributo, automáticamente se crea una instancia de un objeto Processing asociado a dicho elemento canvas del HTML5.

En cualquier momento, desde Javascript, podremos acceder a la instancia del objeto Processing asociado al canvas por medio de su identificador.

objetoProcessing = Processing.getInstanceById('canvasdesarrolloweb');

Nota: Hay que fijarse que hemos enviado como parámetro a getInstanceById() la cadena 'canvasdesarrolloweb' que es el identificador que le colocamos al elemento canvas. Por supuesto, podríamos seleccionar de esta forma cualquier objeto Processing de cualquier elemento canvas, si es que hay más de uno en la página. También es importante decir que, si no hubiera un identificador en el elemento canvas al que queremos acceder, también podríamos seleccionarlo a partir del array Processing.instances[], indicando entre los corchetes el índice del elemento canvas que queríamos recuperar.

Una vez hemos recibido esa instancia, guardada en la variable objetoProcessing, podemos acceder a todo el API de Processing.js para hacer cosas sobre ese canvas estando en funciones Javascript. El resultado es que podremos invocar cualquier tipo de método de los existentes en Processing.js como si estuviéramos en el lenguaje Processing, por ejemplo:

ObjetoProcessing.noLoop();

Eso detendría la animación del elemento canvas asociado al objeto Processing habíamos recuperado.

Ejemplos de acceso al API de Processing desde Javascript

Si aun no te queda claro para qué sirve todo eso, piensa en cómo harías una animación que se modificase cuando se hacen cosas sobre la página, como pulsar un botón. Para definir cosas a hacer al pulsar un botón debemos generar un evento click y programar con Javascript el efecto a producir como respuesta al evento. Esa función Javascript debería poder hacer cosas sobre la animación y para ello necesitas invocar métodos de los que estaban disponibles en el lenguaje Processing, pero date cuenta que tu evento tiene código Javascript y no código Processing.

En cualquier caso, quizás todo esto quede más claro cuando veamos un ejemplo. Por ello hemos preparado un ejercicio en el que tenemos una animación y por medio de Javascript la modificamos. En la página se mostrará una animación de un cuadrado y un círculo y existirán diversos controles Javascript para alterar la animación.

Podemos ver el ejemplo en marcha en una página aparte.

Tenemos un elemento canvas:

<canvas id="micanvas" data-processing-sources="circulos-cuadrados-opacidad.pjs"></canvas>

La animación se cargó por medio del archivo "circulos-cuadrados-opacidad.pjs" que tiene el código Processing para generar el movimiento.

float desplazamiento = 0;
boolean cuadrado = true;
boolean circulo = true;

void setup(){
   size(250,250);
   cambiarColor(50);
}

void draw() {
   background(200,200,200);
   if(cuadrado){
      rect(125-sin(desplazamiento)*50,50-cos(desplazamiento)*50,80,80)
   }
   if(circulo){
      arc(120+sin(desplazamiento)*25, 100+cos(desplazamiento)*25, 150, 150, 0, 2*PI);
   }
   desplazamiento = (desplazamiento + 0.1)%50
};

void cambiarColor(opacidad){
   fill(80,80,180,opacidad);
   stroke(0,150,100,opacidad)
}

A) Acceder al API de Processing desde Javascript

En primer lugar vamos a ver cómo invocar funciones del API de Processing desde Javascript, para modificar un elemento CANVAS.

Para ello tenemos un botón HTML.

<button onclick="cambiaBorde(255)">Cambia el color del borde a blanco</button>

Y ese botón tiene definido un evento onclick que llama a una función Javascript que debe cambiar el color del borde de los dibujos realizados por Processing.

function cambiaBorde(color){
miInstanciaProcessing = Processing.getInstanceById('micanvas');
miInstanciaProcessing.stroke(color, color, color);
}

Dentro de esa función queremos cambiar el color que se utiliza como borde en la animación y para ello existía el método stroke() de Processing. Pero primero tenemos que recuperar el la instancia del objeto Processing asociada a ese canvas, por medio del comentado método getInstanceById(), enviando como parámetro el identificador del canvas.

miInstanciaProcessing = Processing.getInstanceById('micanvas');

Luego, gracias a esa instancia, podemos invocar cualquier método de Processing, como en este caso stroke(), enviando el color que queremos asignar.

miInstanciaProcessing.stroke(color, color, color);

B) Acceso a funciones creadas en el código Processing

En ese mismo sentido, en el ejemplo se realizan diversas acciones para modificar la animación desde Javascript. Por ejemplo, hay una opción para cambiar la opacidad de un elemento y colocar aquella que se marcó en un campo desplegable de selección. Tenemos este código del SELECT.

<select id="selectopacidad" onchange="cambiarOpacidad()">
<option value="0">Transparente</option>
<option value="50" selected=1>casi transparente</option>
<option value="127">Mitad y mitad</option>
<option value="190">Casi opaco</option>
<option value="255">Opaco</option>
</select>

Le hemos definido un evento onchange que invoca a la función Javascript cambiarOpacidad(), cuyo código es el siguiente:

function cambiarOpacidad(){
miInstanciaProcessing = Processing.getInstanceById('micanvas');
miInstanciaProcessing.cambiarColor(document.getElementById("selectopacidad").value);
}

Como puedes ver, accedemos igual que antes al objeto Processing asociado al canvas. Seguidamente utilizamos esa instancia, pero no para invocar un método del propio API de Processing, sino para invocar una función que fue definida por nosotros mismos en el código Processing asociado al canvas.

En el archivo "circulos-cuadrados-opacidad.pjs" teníamos el código Processing:

void cambiarColor(opacidad){
   fill(80,80,180,opacidad);
   stroke(0,150,100,opacidad)
}

Pues a esa función, que pertenece al lenguaje Processing, la podemos invocar también desde Javascript, como si fuera una función del API de Processing.

miInstanciaProcessing.cambiarColor(document.getElementById("selectopacidad").value);

Además, vemos que se le está enviando el value del SELECT, para que esa función nos cambie la opacidad de los dibujos realizados en el canvas, a aquello que fue definido en dicho campo de formulario.

C) Acceso a variables globales definidas en el código Processing

El ejemplo se completa con un par de controles checkbox para definir si se muestran o no los diujos del cuadrado y el círculo.

<input type="checkbox" checked=1 id="mostrarcuadrado" onchange="cambiaMuestraCuadrado()"> Mostrar cuadrado
<br>
<input type="checkbox" checked=1 id="mostrarcirculo" onchange="cambiaMuestraCirculo()"> Mostrar círculo

Al marcarlos o desmarcarlos queremos que aparezcan o desaparezcan el cuadrado o el círculo de la animación.

Si nos fijamos en el código Processing.js habíamos colocado algunas variables globales.

boolean cuadrado = true;
boolean circulo = true;

Esas variables boleanas me sirven para definir si queremos que se vean el cuadrado o el círculo en la animación. Los valores de esas variables se pueden cambiar desde el código Processing pero, sin embargo, no he encontrado manera de acceder a ellas directamente a través de Javascript.

Por ello entiendo que se deben tratar como variables privadas a Processing. Debido a ello, si queremos modificar sus valores desde Javascript, tendremos que crear dentro del código Processing unas funciones que nos permitan modificarlas.

void muestraCirculo(sino){
   circulo = sino
}

void muestraCuadrado(sino){
   cuadrado = sino
}

Podríamos acceder a esas funciones ahora desde Javascript y por tanto cambiar el valor de las variables boleanas.

Para ello hemos definido las siguientes funciones, que se invocan como respuesta al cambio de los campos checkbox (Fíjate el evento onchange que hemos colocado en los INPUT de los checkbox).

function cambiaMuestraCuadrado(){
miInstanciaProcessing = Processing.getInstanceById('micanvas');
miInstanciaProcessing.muestraCuadrado(document.getElementById("mostrarcuadrado").checked);
}
function cambiaMuestraCirculo(){
miInstanciaProcessing = Processing.getInstanceById('micanvas');
miInstanciaProcessing.muestraCirculo(document.getElementById("mostrarcirculo").checked);
}

Eso es todo! Ya tenemos un ejemplo completo de comunicación con Processing desde Javascript. Recuerda que puedes ver el código fuente de los scripts generados para más información.

En el siguiente artículo presentaremos otro ejemplo completo de comunicación entre Processing y Javascript, que podrá ayudarte a afianzar los conocimientos adquiridos.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual