ES

www.codigo-facil.com > Mi framework en Javascript, efectos parte 1

Mi framework en Javascript


Capitulo 5 : Efectos parte 1

Capitulos

Mi framework en Javascript, introduccion

Primer capitulo de una serie donde veremos en que consiste y como desarrollar nuestro propio framework en javascript.

Mi framework en Javascript, la clase principal

En este capitulo definiremos la base de nuestro framework, crearemos una clase base a partir de la cual iremos incluyendo todas las funcionalidades del framework.

Mi framework en Javascript, los selectores

Los selectores son uno de los pilares fundamentales a partir del cual se desarrollan el resto de funcionalidades del framework. En el capitulo que nos ocupa veremos que son exactamente y como implementarlos.

Mi framework en Javascript, la funcion CSS

En este capitulo veremos como implementar una funcion, que nos permita cambiar el aspecto de cualquier elemento incluido en nuestra pagina html, a traves de la utilizacion de las propiedades CSS.

Mi framework en Javascript, efectos parte 1

En este capitulo vamos a incluir una funcionalidad a nuestro framework que nos permita aplicar efectos para poder mover o cambiar de tamaño cualquier elemento de nuestro documento HTML.

Mi framework en Javascript, efectos parte 2

En este articulo vamos a desarrollar una funcion para nuestro framework, que nos permita crear efectos de transicion entre 2 colores diferentes.

Mi framework en Javascript, transparencias

En este articulo veremos como modificar la propiedad alpha de cualquier elemento de nuestro documento HTML, para crear asi transparencias haciendo mas artactivo el diseño de nuestra pagina.

Introduccion :


En el capitulo anterior implementamos la funcion css  que nos permitia cambiar los atributos css de cualquier elemento de nuestro documento HTML.

En el capitulo que nos ocupa hoy vamos a incluir una funcionalidad que nos permita aplicar animaciones o efectos a cualquier elemento a traves de los atributos CSS, lo que nos permitira crear animaciones de una forma sencilla para dotar de mas dinamismo a nuestra pagina HTML.

 Puedes ver el resultado final de lo que vamos a implementar en este capitulo en la siguiente direccion:

Implementacion :


Como es habitual, solo recordar que el codigo que vamos a ver a continuacion habra que incluirlo dentro de la clase principal implementada en el capitulo 2, en el espacio reservado a incluir nuevas funcionalidades, despues de la ultima funcion que hayamos creado.

Dentro de la implementacion solo destacar, sin entrar en mas detalles por ahora, que basicamente he creado 2 funciones :
  1. Una funcion que es la que invocaremos nosotros para aplicar el efecto que deseemos, con los correspondientes parametros.
  2. La segunda funcion sera invocada por la primera de forma automatica y se encargara de aplicar el efecto desde el inicio hasta su finalizacion.
Pero nada mejor que ponernos manos a la obra para tenerlo todo mas claro.

Implementando la primera funcion :


Como es habitual vamos a empezar viendo el codigo que implementaremos en la funcion, para despues comentar algunas partes o detalles del mismo. No olvidar que esta sera la funcion que invocaremos cuando queramos aplicar un efecto del tipo que vamos a ver en este capitulo.
  1. /*
  2. Definicion de la funcion que invocaremos para aplicar el efecto
  3. */
  4. this.animate = function(type,option,sleep,selector)
  5. {
  6.   /*
  7.   Compruebo que el existen objetos con el selector actual
  8.   */
  9.   if (this.objs.length>0)
  10.   {
  11.     /*
  12.     Esta primera parte no prestaremos atencion pues hace referencia
  13.     a efectos de color que veremos en el siguiente capitulo
  14.     */
  15.     if (type.toUpperCase() == 'BACKGROUNDCOLOR' || type.toUpperCase()=='COLOR' ||         type.toUpperCase() == 'BORDERCOLOR')
  16.     {
  17.       this.animateColor(type,option,sleep,selector);  
  18.     }
  19.     else
  20.     {
  21.     /*
  22.     Esta es la parte importante de la funcion
  23.     */

  24.       /*
  25.       Si el parametro selector no existe lo cojo del que esta disponible
  26.       dentro del framework
  27.       */
  28.       if (!selector )
  29.         selector = this.selector;

  30.       /*
  31.       En caso de no existir este tipo de efecto en la cache 
  32.       del framework lo creo, y si existe para el posible efecto 
  33.       que este ejecutandose para este selector.
  34.       */
  35.       if (!apiJS.objs[selector].animate[type])
  36.         apiJS.objs[selector].animate[type] = {}
  37.       else
  38.         clearTimeout(apiJS.objs[selector].animate[type]['timer']);

  39.       /*
  40.       Si existe este parametro entonces es pq he qerido hacer 
  41.       una pausa antes de aplicar el efecto, debo preparar una 
  42.       cadena de texto con los parametros que le he pasado dentro 
  43.       del objeto option, para ello llamo a la funcion "this.ArraytoStr", 
  44.       que aun no ha sido implementada, y veremos mas adelante 
  45.       en este capitulo.
  46.       */
  47.       if (sleep && sleep!=-1)
  48.         {
  49.           apiJS.objs[this.selector].animate[type]['option'] = option;
  50.           var vars = "apiJS.objs['"+this.selector+"'].obj.animate('" + type + "',"+this.ArraytoStr(option)+",-1,'"+this.selector+"')";
  51.           apiJS.objs[this.selector].animate[type]['timer'] = window.setTimeout(vars,sleep);
  52.           return this;
  53.         }
  54.       else
  55.       if (sleep == -1)
  56.         option = apiJS.objs[this.selector].animate[type]['option'];

  57.       /*
  58.       Compruebo la existencia de -option["ini"]- , para en caso de que 
  59.       sea necesario inicializarlo, para ello intento tomar el valor css 
  60.       que pueda tener en funcion al tipo de efecto, que es en si un 
  61.      atributo css.
  62.       */
  63.       if (!option['ini'])
  64.         option['ini'] = parseInt(apiJS.objs[selector].obj.objs[0].style[type]);

  65.       if (!option['ini'])
  66.         option['ini'] = 0;

  67.       /*
  68.       El parametro -option['value']- es el que determina donde termina 
  69.       el efecto, lo convierto al tipo entero
  70.       */
  71.       option['value'] = parseInt(option['value']);

  72.       /*
  73.       Ahora determino que tipo de operacion se va a realizar, en 
  74.       funcion al valor inicial y final, el resultado lo guardo en :
  75.       option['sign']
  76.       */
  77.       option['sign'] = 1;
  78.       if (option['ini'] > option['value'])
  79.         option['sign'] = -1;

  80.       /*
  81.       Compruebo la existencia del parametro que me determina 
  82.       la duracion (en tiempo) del efecto, en caso de no exirtir le 
  83.       doy un valor por defecto
  84.       */
  85.       if (!option['delay'])
  86.         var delay=400;
  87.       else 
  88.         var delay=option['delay'];

  89.       /*
  90.       A continuacion vamos a inicializar al parametro add. Esta es una parte importante 
  91.       pq vamos a obtener el valor en funcion a las unidades de desplazamiento que va a 
  92.       realizar el efecto y el tiempo de duracion de dicho efecto, Este resultado lo dividiremos 
  93.       por una constante, que son los milisegundos de espera hasta la siguiente ejecucion, en 
  94.       este caso 16, pq es el coeficiente resultante si queremos dibujar 60 imagenes por segundo
  95.       */
  96.       var add = ((option['value'] > option['ini']) ? (option['value']-option['ini']) : (option['ini']-option['value'])) / (parseInt(delay) / 16);

  97.       option['add'] = option['sign']*add;

  98.       /*
  99.       Registro el momento en el que deberia finalizar el efecto para poder modificar el 
  100.       parametro -oprion['add']- , esto es asi pq podria existir diferencias en el tiempo de 
  101.       ejecucion segun el navegador y el ordenador, asi puedo tener mas control.
  102.       */
  103.       option['dFin'] = (new Date()).getTime()+parseInt(delay);

  104.       /*
  105.       El parametro -option['effect']- se utiliza para incluir un pequeño efecto de 
  106.       rebote al terminar la ejecucion del efecto principal
  107.       */
  108.       if (option['effect'])
  109.       {
  110.         option['effeT']=2;
  111.         if (parseInt(option['effect']))
  112.           option['effVal']=parseInt(option['effect']);
  113.       }

  114.       /*
  115.       Asigno a la propiedad css que dice el efecto, su valor inicial
  116.       */
  117.       this.css(type,option['ini']+'px');

  118.       /*
  119.       Registro la cantidad total de movimiento que va a realizar el efecto, 
  120.       para establecer despues una propocion de tiempo en caso de  
  121.       existir el efecto rebote al final de la animacion principal
  122.       */
  123.       if (option['sign']>0)
  124.           option['total'] = option['value']-option['ini'];
  125.      else
  126.           option['total'] = option['ini']-option['value'];

  127.       /*
  128.       Registro en la cache del nucleo del framework los parametros utilizados
  129.       */
  130.       apiJS.objs[selector].animate[type]['option'] = option;

  131.       /*
  132.       Hago una comprobacion de que el valor inicial y final son distintos para lanzar el efcto.
  133.       La segunda funcion que veremos mas adelante sera la que se encargue de realizar 
  134.       el efecto hasta su finalizacion.

  135.       Al finalizar el efecto se comprueba la existencia del parametro -option['exec']- 
  136.       este parametro lo podemos utilizar para asignar una funcion que se invocara al 
  137.       finalizar el efecto

  138.       Destacar que utilizo cache del framework para centralizar la ejecucion del 
  139.       "setInterval" para poder tener un control sobre su ejecucion. Como vemos 
  140.       se ha creado una cache para un selector y un tipo de efecto, asi podemos 
  141.       tener en funcionamiento varios efectos a la vez para un mismo selector
  142.       */
  143.       if(option['ini'] != option['value'])
  144.       {
  145.       apiJS.objs[selector].animate[type]['timer'] = window.setInterval("apiJS.startAnim('" + selector + "',' "+ type + "')",16);
  146.       }
  147.       else
  148.       {
  149.         if (option['exec'] && typeof option['exec']=='function')
  150.           {
  151.           option['exec'].call(apiJS.objs[selector]['obj']);
  152.           option['exec']=null;
  153.           }
  154.         else
  155.         if (option['exec']) eval(option['exec']);
  156.       }
  157.       return this;
  158.     }
  159.   }

  160. }

Antes de continuar :


No podemos olvidar que en codigo anterior hemos utilizado un metodo del framework que aun no habiamos implementado todavia, el codigo al que hago referencia es el siguiente :

  1. this.ArraytoStr(option)

La implementacion de esta funcion la vamos a ver a continuacion. Su objetivo es el siguiente: tomar el objeto que le pasomos como parametro y convertirlo a una cadena de texto que sea compatible para su posterior ejecucion en window.setTimeout , window.setInteval o eval

La implementacion de esta funcion o metodo es la siguiente :

  1. this.ArraytoStr = function (array)
  2. {
  3.   var str='{';
  4.   for (var name in array) 
  5.   {
  6.   if (typeof array[name]!='function')
  7.     str=str+name+":'"+array[name]+"',";
  8.   }
  9.   str=str.substring(0,str.length-1);
  10.   str=str+'}';
  11.   return str;
  12. }

Comentarios de la funcion :

Como podemos comprobar la funcion no tiene mucha mas historia, se encarga de recorrer el array y contruir la cadena de texto con el formato correcto para su posterior ejecucion. Al final del bucle se elimina el ultimo caracter para evitar que provoque el error.

Como es un metodo destinado a ser invocado por otras funciones, lo colocaremos al inicio de la zona destinada a las nuevas funcionalidades.

Analisis de la funcion "animate" :


Es momento de analizar la primera funcion que habiamos visto al principio. Vamos a empezar viendo con detalle los diferentes parametros que podemos utilizar para invocar  la funcion:
  • Type : Parametro tipo cadena de texto y obligatorio, es el que determina el tipo de efecto a aplicar y podra tomar cualquier valor que tenga su equivalencia en propiedad css. Asi por ejemplo para mover horizontalmente utilizaremos marginLeft, para cambiar el tamaño seria width o height, y asi podemos configurar multitud de efectos con una sola funcion.
  • Option : Es un objeto y sirve para configurar el efecto. Podemos utilizar los siguientes parametros :

    option['value'] : Para indicar el valor final del efecto.

    option['ini'] : Valor opcional, sirve para decir donde queremos que se inicie el efecto. En caso de omision se tomara el valor actual de la propiedad que se corresponda con el tipo de efecto.

    option['delay'] : Valor opcional, por defecto tomara el valor 400. Sirve para especificar, en milisegundos, la duracion del efecto.

    option['effect'] : Parametro opcional y sirve para indicar  si queremos un efecto rebote al finalizar la animacion principal. El valor puede ser un entero y determinara el espacio de rebote.

    option['exec'] : Parametro opcional y que puede ser una cadena de texto o una funcion en javascript. Nos permite incluir una funcion a ejecutar al finalizar la ejecucion del efecto. Esto nos permitira encadenar efectos para crear animaciones mas complejas.

  • Sleep : Parametro tipo entero y opcional que sirve para poder aplicar un retardo en el momento de lanzar un efecto, el tiempo se define en milisegundos.
  • Selector : Parametro opcional y del tipo string, se utiliza de forma automatica por la misma funcion en caso de haber especificado el parametro "sleep" asi que no hace falta prestarle mas atencion.
Una vez que hemos visto los parametros que admite la funcion "animate" vamos a ver un ejemplo de una posible ejecucion de la misma :

  1. <script>
  2. $("capa1").animate("marginLeft" , {"value" : 300 , "ini" : 0 , "delay" : 1000} );
  3. </script>

Otro detalle que queria comentar, para evitar confusiones, lo encontramos al inicio de la funcion, cuando se comprueba si el tipo de efecto va relacionado con el color de texto (color), o el color de fondo (backgroundColor). Añadi esta comprobacion para poder dejar a la funcion animate como metodo principal para la ejecucion de efectos. La implementacion de los efectos de color la veremos en el siguiente capitulo.

El resto de codigo se encarga de inicializar y de comprobar todos los parametros necesarios para la posterior ejecucion del efecto por parte de la funcion que vamos a ver a continuacion.

Implementando la segunda funcion :


Una vez que ya hemos desarrollado la funcion encargada de realizar todos los preparativos necesarios para la ejecucion del efecto, vamos ahora a implementar la funcion encargada de realizar el efecto desde su inicio hasta su finalizacion.

El codigo de esta funcion es el siguiente :
  1. this.startAnim = function(selector,type,bucle)
  2. {
  3.   /*
  4.   Empiezo omprobando que existe el objeto en la cache del framework
  5.   */
  6.   if (apiJS.objs[selector])
  7.   {
  8.   /*
  9.   Recupero los parametros de configuracion registrados para este efecto
  10.   */
  11.   var option = apiJS.objs[selector].animate[type]['option'];

  12.   /*
  13.   Obtengo el tiempo que queda para la finalizacion del efecto
  14.   */
  15.   var time = option['dFin']-(new Date()).getTime();

  16.   /*
  17.   Actualizo el valor actual segun avanza el efecto
  18.   */
  19.   option['ini'] = option['ini'] + option['add'];

  20.   /*
  21.   Compruebo si se ha cumplido el tiempo para la ejecucion del efecto.

  22.   En caso de no haberse cumplido actualizao el valor de incremento 
  23.   en funcion a la distancia y el tiempo restante factorizado con el ciclo de 
  24.   repeticion, definido en 16 (60 imagenes por segundo)
  25.   
  26.   En caso de haberse cumplido el tiempo actualiza directamente el valor 
  27.   actual por el valor final para forzar la finalizacion del efecto.
  28.   */
  29.   if (time>0)
  30.     {
  31.     var add=((option['sign']>0)?(option['value']-option['ini']):(option['ini']-option['value']))/(time/16);
  32.     add = add*option['sign'];
  33.     option['add'] = add;
  34.     }
  35.   else
  36.     option['ini']=option['value'];

  37.   /*
  38.  Verifico que el parametro actual esta dentro del rango delimitado por el valor final, 
  39.   caso de estar fuero el valor inicial toma el valor final para terminar asi el efecto. 
  40.   */
  41.   if ( (option['ini']>option['value']&& option['sign']>0) || (option['ini']<option['value']&& option['sign']<0) )
  42.     option['ini']=option['value'];

  43.   /*
  44.   Asigno a la correspondiente propiedad css el valor actual  
  45.   */
  46.   apiJS.objs[selector].obj.css(type,option['ini']+'px');

  47.   /*
  48.   Compruebo la existencia de alguna funcion a ejecutar a cada 
  49.   cinclo de repeticion del efecto  
  50.   */
  51.   if (option['action'])
  52.      eval(option['action']);

  53.   /*
  54.   Verifico que el tiempo de ejecucion del efecto no ha terminado.

  55.   En caso de no haber terminado refresco lo valores registrados en 
  56.   la cache para la siguiente ejecucion del ciclo del efecto.

  57.   En caso de haberse cumplido se para el ciclo ejecutado por setInterval 
  58.   y elimino la bandera creada para el correspondiente selector que indicaba 
  59.   que estaba bajo la ejecucion de un proceso automatizado.
  60.   */
  61.   if (time>0 )
  62.     apiJS.objs[selector].animate[type]['option']=option;
  63.   else
  64.     {
  65.       delete apiJS.objs[selector]['working'];
  66.       clearTimeout(apiJS.objs[selector].animate[type]['timer']);

  67.     /*
  68.     Verifico si se ha configurado la ejecucion del efecto rebote.

  69.     En caso de haberse configurado establezco la duracion del efecto 
  70.     proporcionalmente a la duracion del efecto actual y la distancia 
  71.     recorrida por el efecto actual. si el valor es demasiado pequeño se 
  72.     configura por defecto a 100 mili segundos, para que se pueda apreciar.
  73.     Destacar que el efecto rebote tiene dos partes, una que va hacia el 
  74.     lado contrario al efecto pricipal y la otra parte es la que retoma la 
  75.     direccion principal.

  76.     En caso de no haber configurado el efecto rebote o que el mismo ya 
  77.     haya concluido, compruebo si se ha configurado alguna funcion a 
  78.     ejecutar al termino del efecto, para en caso afirmativo invocarla.
  79.     */
  80.       if (option['effeT'] && option['effeT']>=0)
  81.       {
  82.         option['delay'] = (parseInt((option['delay']*option['effVal'])/option['total']));
  83.         if (option['delay']<100)
  84.           option['delay'] = 100;
  85.         option['effeT']--;
  86.         if(option['effeT']>=0)
  87.           {
  88.             if (option['effVal'])
  89.               {
  90.                 if ((option['sign']<0))
  91.                   option['value'] = option['value']+option['effVal'];
  92.                 else
  93.                   option['value'] = option['value']-option['effVal'];
  94.                 apiJS.objs[selector].obj.animate( type , {'exec' : option['exec'] , 'value' : option['value'] , 'effVal ': option['effVal'] , 'effeT' : option['effeT'] , 'delay' : option['delay']});
  95.               }
  96.             else
  97.               apiJS.objs[selector].obj.animate( type , {'exec' : option['exec'] , 'value' : ( ( option['sign'] < 0 )  ? ( parseFloat( option['value'] ) + 10 ) : ( parseFloat( option['value'] ) - 10)) , 'effeT' : option['effeT'] , 'delay' : option['delay']});
  98.           }

  99.       }
  100.       else
  101.       {
  102.         if (option['exec'] && typeof option['exec']=='function')
  103.         {
  104.           option['exec'].call(apiJS.objs[selector]['obj']);
  105.           option['exec']=null;
  106.         }
  107.         else
  108.         if (option['exec'])
  109.           eval(option['exec']);
  110.       }

  111.     }
  112.   }
  113. }

Conclusiones finales :


Ya tenemos las 2 funciones principales para poder aplicar efectos de movimiento o tamaño a cualquier elemento de nuestra pagina, de forma sencilla y con un codigo de ejcucion simple y elegante, pudiendo configuar el efecto desde su duracion hasta el valor inicial y final, ademas de otros parametros mas complejos como asignar funciones a ejecutar en su finalizacion.

Ya podemos decir que empezamos a tener una api en javascript interesante que nos permite cambiar atributos css o aplicar efectos a los elementos de nuestro documento HTML.

Antes de terminar solo recordar que tienes un ejemplo de la ejecucion del codigo implementado en este capitulo en la siguiente direccion :


Hemos llegado al final del capitulo, no olvideis que en la siguiente publicacion veremos los efectos relacionados con el color, para poder cambiar el color de fondo o del texto. 

Me despido aqui y como siempre gracias a tod@s por vuestro apoyo y nos vemos en la siguiente publicacion.

Ultimas noticias

Crea tu propio framework en javascript

Recopilacion de articulos donde mostrare paso a paso como podemos crear nuestro propio framework en javascript, totalmente funcional y listo para ser utilizado en nuestros futuros proyectos.

Para mas informacion :

Tutorial para crear tu propio FrameWork en JavaSript

Más información
13/12/2013 11:42:57

Como crear una DLL en delphi?

En esta serie de 2 capitulos veremos como crear y utilizar una DLL en Delphi.

Abajo os dejo los enlaces a estos 2 capitulos que componen este mini tutorial, espero que sea de vuestro agrado :

Capitulo 1 : Creacion y utilizacion de una DLL

Capitulo 2 : Creacion de un formulario dinamico utilizando una DLL
Más información
19/09/2013 17:35:59

Ya puedes publicar tu opinion

A partir de ahora ya puedes comentar todas las publicaciones que encuentres en el portal.

Podras opinar tanto si algo te gusta como si no, o si crees que es conveniente completar alguna publicacion, ya que la encuentras incompleta o erronea.

O simplemente por si nos quieres felictar por algo bien hecho :-).

Valoraremos cualquier critica que nos puedas hacer.
Más información
20/05/2013 15:30:10

Tutorial PHP5

Fundamentos de la programacion orientada a objetos
Un interesante tutorial repartido en una serie de capitulos donde se tratan los conocimientos basicos de la programacion orientada a objetos (POO) en PHP5.

Para mayor informacion siga el siguiente enlace :

Tutorial POO en PHP

Más información
04/09/2013 15:44:29
0