Mundo Web
manuales - recursos - gráficos - programación...

Home - WebScript - Efectos - Cursor dinámico I

Cursor dinámico I
por Luciano Moreno, del departamento de diseño web de BJS Software.

 

Vamos a estudiar un efecto de animación asociado al movimiento del ratón, en el que un mensaje se vaa ir desplazando por la ventana del navegador siguiendo al puntero de éste. Además, este script en concreto presenta la gracia adicional de que el desplazamiento del texto del mensaje se produce letra por letra, creando un bonito efecto de ondulación.

El script es una variante del aparecido en The JavaScript Source ( http://javascript.internet.com ), original de kurt.grigg@virgin.net, que he traducido, simplificado, comentado y adaptado a Nestcape Navigator 6x. Al no ser pués de mi propiedad, si deseáis usarlo en vuestras páginas tendréis que pedir autorización al autor original del mismo. Mi autorización para usar los cambios ya la tenéis de antemano.

El código necesario es el siguiente:

<html>
<head>
    <title>HTMLWeb - WebScript - Cursores - Cursor animado I</title>
</head>

<body bgcolor="#ffff99">

  <script language="JavaScript" type="text/javascript">

      
      /**
      * configuracion de variables generales
      * var mensaje >> texto a mostrar siguiendo al cursor
      * var font    >> familia de la fuente
      * var size    >> size de la fuente ( entre 1 y 7 )
      * var color   >> color de la fuente (valor hexadecimal o nombre estandar ingles
      * var velocidad >> velocidad de colocacion de las letras a una nueva posicion
      */

      mensaje = 'Bienvenido a HTMLWeb';
      font = 'Verdana,Arial';
      size = 2;
      color = '#006600';
      velocidad = 0.7;

      /**
      * definicion de variables auxiliares para acceder a las capas en cada navegador
      */
      n4 = (document.layers);
      ie = (document.all);
      n6 = (document.getElementById);

      /**
      * separamos el mensaje en los cacateres que lo forman y obtenemos el numero de ellos
      * (los espacios y la coma cuentan como un caracter mas)
      */
      mensaje = mensaje.split('');
      n = mensaje.length;

      /**
      * variables auxiliares de calculo
      * var a  >> contiene el size definido para la fuente multiplicado por 10, para asignar luego
      * a las capas o a los layers esa dimension
      * vars xmouse, ymouse >> definen la posicion inicial del texto, antes de mover el raton
      * var props   >> contiene la cadena que va a definir el aspecto final de la fuente del mensaje
      */
      a = size*10;
      ymouse = 0;
      xmouse = 0;
      props = "<font face="+font+" size="+size+" color="+color+">";

      /**
      * pintamos los layers para Nestcape 4x y las capas para Internet Explorer
      */
      if (n4)
      {
          for ( i = 0; i < n; i++)
              document.write('<layer name="n4mensaje'+i+'" top=0 left=0 height='+a+' width='+a+'><center>'+props+mensaje[i]+'</font></center></layer>');
      }
      else if (ie)
      {
          document.write('<div id="padre" style="position:absolute;top:0px;left:0px"><div style="position:relative">');
          for (i=0; i < n; i++)
              document.write('<div id="iemensaje" style="position:absolute;top:0px;left:0;height:'+a+';width:'+a+';text-align:center">'+props+mensaje[i]+'</font></div>');
          document.write('</div></div>');
      }
      else if (n6)
      {
          document.write('<div id="padre" style="position:absolute;top:0px;left:0px"><div style="position:relative">');
          for (i = 0; i < n; i++)
              document.write('<div id="iemensaje'+i+'" style="position:absolute;top:0px;left:0;height:'+a+';width:'+a+';text-align:center">'+props+mensaje[i]+'</font></div>');
          document.write('</div></div>');
      }
     
      /**
      * capturamos el evento MOUSEMOVE para Nestcape Navigator 4x
      */
      if(n4)
          window.captureEvents(Event.MOUSEMOVE);

     
      /**
      * funcion para obtener las coordenadas del raton en pantalla, sumarle 20 pixels a
      * cada una y asignar estos valores alos variables temporales xmouse, ymouse
      */
      function Mouse(evento)
      {        
          if(ie)
          {
              xmouse = event.x+20;
              ymouse = event.y+20;
          }
          else if(n4 || n6)
          {
              xmouse = evento.pageX+20;
              ymouse = evento.pageY+20;
          }
      }
     
      /**
      * Cada vex que se mueva el raton, llamamos a la funcion anterior, para
      * tener en todo momento valores correctos en las variables temporales
      */
      if(n4)
          window.onMouseMove = Mouse
      else if(ie || n6)
          document.onmousemove = Mouse;
   
      /**
      * declaramos unas matrices globales que van a contener las coordenadas temporales
      * de cada una de las capas de las letras, y las inicializamos con valor 0
      */
      y = new Array();
      x = new Array();
      Y = new Array();
      X = new Array();
      Yaux = new Array();
      Xaux = new Array();

      for (i=0; i < n; i++)
      {
          y[i] = 0;
          x[i] = 0;
          Y[i] = 0;
          X[i] = 0;
          Yaux[i] = 0;
          Xaux[i] = 0;
      }

      /**
      * funcion de posicionamiento de las capas de las letras
      */
      function asigna()
      {
          /**
          * Si se ha escroleado la ventana del navegador, inicializamos en Intenet Explorer
          * en la nueva posicion
          */
          if (ie)
              padre.style.top = document.body.scrollTop;
     
          /**
          * recorremos todas las capas de letras y les asignamos sun nuevas posiciones
          */
          for (i = 0; i < n; i++)
          {
              if(n4)
              {
                  document.layers['n4mensaje'+i].top = y[i];
                  document.layers['n4mensaje'+i].left = x[i]+(i*(a/2));
              }
              else if(ie)
              {
                  iemensaje[i].style.top = y[i];
                  iemensaje[i].style.left = x[i]+(i*(a/2));
              }
              else if(n6)
              {
                  eval("document.getElementById('iemensaje"+i+"').style.top = '"+y[i]+"px'");
                  eval("document.getElementById('iemensaje"+i+"').style.left = '"+(x[i]+(i*(a/2)))+"px'");
              }               
          }
      }

      /**
      * funcion para crear el efecto de onda en el movimiento de cada una de las
      * capas de letra del mensaje
      */
      function ondula()
      {
          /**
          * Las coordenadas de la capa de la primera letra del mensaje viene
          * determinada por la posicion del cursor
          */
         y[0]=Math.round(Y[0] +=((ymouse)-Y[0])*velocidad);
         x[0]=Math.round(X[0] +=((xmouse)-X[0])*velocidad);
                  
          /**
          * Las coordenadas de las siguientes capas vienen determinadas por las de la
          * capa anterior, es decir, la capa de una letra arrastra a la de la letra siguiente
          */
          for (var i = 1; i < n; i++)
          {
              Yaux[i] = Math.round(Y[i]);
              Xaux[i ]= Math.round(X[i]);
             y[i] = Math.round(Y[i]=Yaux[i]+(y[i-1]-Y[i])*velocidad);
             x[i] = Math.round(X[i]=Xaux[i]+(x[i-1]-X[i])*velocidad);
          }
    /**
    * Una vez obtenidas las nuevas posiciones, llamamos a la funcion asigna para que
    * posicione las diferentes capas
    */
          asigna();
    /**
    * Y ahora la funcion se llama a si misma cada 10 milisegundos, creando el efecto
    * dinamico de ondulacion y movimiento
    */
         setTimeout('ondula()',50);
      }

      /**
       *inicializamos la funcion ondula al cargar la pagina,
       * con lo que el sistema queda preparado para actuar en cuanto se mueva el cursor
       * por la ventana del navegador
       */
      window.onload = ondula;

  </script>

</body>
</html>

Consideraciones:

1) El mecanismo del script consiste en separar el mensaje a mostrar en sus letras constituyentes (mediante el método propio de JavaScript split()) y meter cada una de ellas en una capa, para luego ir capturando en todo momento la posición del puntero del ratón y asignar a las capas de las letras una posición relativa a esta captura.

2) Para crear el efecto de ondulación del texto al moverse lo que hacemos es actualizar esta posición de las capas cada 50 milisegundos, pero de tal forma que la posición de una letra viene dada por la de su letra anterior +- un retardo en coordenadas. Es decir, la capa 0 (primera letra) se va directamente al lado del punetro del ratón, la 1 se desplaza cerca de ésta menos un retardo (definido por su posición antigua, la de la capa 0 y un incremento dado por el valor de la variable velocidad), y así sucesivamente.

3) La longitud del mensaje en teoría puede ser cualquiera, pero hay que tener en cuenta que si pasamos de los 20 caracteres en el caso de Nestcape Navigator 6x se produce un retardo cada vez mayor, debido a una sobrecarga de cálculos (debe calcular tantas posiciones como caracteres tenga el mensaje cada 50 milisegundos). Esto no pasa en Internet Explorer y Nestcape 4x, que aguantan mejor este tipo de cálculos.

4) Usamos el método round() del objeto propio Math para obtener valores de coordenadas enteros, quitando los decimales. Este método recibe como argumento un número o expresión numérica válida y retorna el menor número entero por debajo del recibido.

5) En el caso de Nestcape Navigator 4x es necesario capturar el evento del movimiento de ratón (MOUSEMOVE), ya que por defecto no viene activado.

Por lo demás, el código sólo precisa un poco de estudio y unas bases de JavaScript y DHTML.

El resultado del código anterior podéis verlo pinchando aquí .

 


Home - WebScript - Efectos - Cursor dinámico I