Menu giratorio con efectos 3D

Crea tu menu dinámico con efectos 3D en flash en un simple script. Consigue los ejemplos gratis para ilustrar el manual.

 

En primer lugar, para poder realizar este ejemplo debes haber leído el artículo Movimiento rotativo, en el que se explican las directrices para poder entender y utilizar las funciones adecuadas para realizar un efecto de giro.

Dicho esto podemos empezar, como nuestro menú esta realizado en flash, debemos saber unas peculiaridades que hacen que la programación de este movimiento sea un poco distinta.

Cuando hablábamos del sistema de referencia lo considerábamos centrado en el origen, pues bien, en flash el sistema de referencia tiene el punto (0,0) en la parte superior izquierda y los ángulos son positivos cuando giramos en el sentido de las agujas del reloj y negativos en caso contrario.

 



Partimos de un nuevo documento de ActionScript2.0, el cual contiene en la biblioteca dos MovieClips, esfera y sombra. El primero contiene una esfera dibujada y el MoviClip sombra para darle un efecto 3D.

Descarga el archivo fla preparado.

En primer lugar, vamos a la biblioteca y pulsando el botón secundario del ratón accedemos a la opción linkage ... Marcamos la opción Export for ActionScrit y asignamos en el campo de texto Identifier el nombre de instancia que queramos en nuestro caso “esfera”.

Hecho esto, marcamos el primer fotograma de la capa acciones, y presionamos F9 para entrar en el manu de edición de ActionScript.
En la primera parte del script definimos las variables y constantes que utilizaremos más adelante. Las constantes xo y yo son la posición del centro del escenario que después utilizaremos para centrar el movimiento, estas dos son indispensables para paliar el sistema de coordenadas de flash que comentábamos con anterioridad.

 
// Definimos constantes para centrar el centro del menú

var xo:Number = Stage.width/2;
var yo:Number = Stage.height/2;

// Definimos constantes para caracterizar el giro

var amp_x:Number = 150; // Amplitud de la elipse
var amp_y:Number = 35; // Altura de la elipse
var num_objects:Number = 10; // Cantidad de elementos
var start_angle:Number = 0; // Angulo inicial
var speed_factor:Number = 100; // Velocidad del movimiento
var incr_angle:Number = 360 / num_objects; // Esta función coloca las esferas de manera equidistante por la elipse

 
Despues de este paso incluiremos la siguiente parte:

 
// Insertamos las esferas en la línea de tiempo

for( i = 0; i < num_objects; i++ ){
_root.attachMovie( "esfera", "esfera" + i, i );
}

 
Mediante este bucle incluimos las esferas en el escenario. El bucle recorre desde el 0 hasta el número de objetos que le designamos en la variable num_objects – 1. En cada iteración realiza un llamada a la función attachMovie que coge el nombre del primer argumento, lo busca en la biblioteca, y lo inserta en el escenario con el nombre de instancia que asignamos en el segundo argumento (“esfera”+i genera: esfera0, esfera1, esfera2… ), el último argumento es el nivel donde se carga el objeto (más arriba o más abajo), aunque después lo modificaremos, utilizamos el valor de i para asignar el nivel de cada objeto.

Una vez insertados los elementos en el escenario e instanciados, necesitaremos un bucle que se repita infinitamente para que actúe como elemento listener.

 
// Bucle que realiza la actualización del movimiento

this.onEnterFrame = function(){
// Actualiza el incremento del ángulo
var angle_change:Number = Math.round((_xmouse - xo)/speed_factor);
start_angle += angle_change;

// Recorremos todos los objetos
for (var i:Number = 0; i < num_objects; i++){
thisObj = this["esfera"+i];
place_obj(thisObj,i);
}
}

El objeto onEnterFrame es un bucle que se repetirá infinitamente. Esto nos permite asignar características a nuestra película como esperar a que el usuario realice una acción. Pues bien, este bucle estará ejecutándose siempre para que obtenga la posición del mouse en todo momento, ya que de esta posición depende el movimiento de nuestro menú ( del mismo modo que depende del mouse puede depender de la pulsación de alguna tecla… ).

Dicho esto, la primera línea de dentro del bucle crea una variable angle_change, que guarda un número que es la variación del ángulo de cada una de las esferas. Esta variación la obtenemos de la siguiente forma, cogemos la posición del mouse respecto a x (_xmouse) y le restamos la xo para desplazar el origen al centro del escenario y lo dividimos por un factor de velocidad (variable que determinara la velocidad del movimiento, cuando más alta menor velocidad y viceversa). A este valor le aplicamos Math.Round para redondear los decimales. Con esto conseguimos lo siguiente, cuando el ratón este en el centro del escenario la variación será 0 y cuando más lejos este de este la variación será más grande en valor absoluto, ya que si el mouse está en la parte derecha la variación será positiva y si está en la parte izquierda será negativa. Este cambio de signos nos permite que el movimiento cambie de sentido.

Lo que hacemos ahora es sumar esta variación al ángulo inicial o punto de partida de cada esfera. Y por ultimo necesitamos un bucle que recorra todas las esferas y actualice la posición de cada una en función de la variación del ángulo. Creamos un bucle for como el anterior, pero en este asignamos el nombre de instancia de cada esfera a la variable thisObj en cada iteración. Y llamamos a la función place_obj que modifica posición de la esfera que le pasamos por argumento e ir actualizando las posiciones todas las esferas.

 
_root.attachMovie( "esfera", "esfera" + i, i );
}


// Función que obtiene la posición de cada esfera

function place_obj(thisObj,i) {

// calcula el ángulo que forma el objeto
var angulo:Number = i * incr_angle + start_angle; // en grados
var angulo_rad:Number = angulo * Math.PI/180; // en radianes

// Incluye la esfera en la elipse
thisObj._x = xo + amp_x * Math.cos(angulo_rad);
thisObj._y = yo + amp_y * Math.sin(angulo_rad);

// Escalamos las esferas efecto profundidad
thisObj._yscale = thisObj._xscale = ( thisObj._y - 100 ) * 0.7 + 100;

// Asignamos nuevos niveles para que no se superpongan
thisObj.swapDepths( thisObj._y );
}

// Bucle que realiza la actualización del movimiento

this.onEnterFrame = function(){


 
En primer lugar definimos la función place_obj con los argumentos thisObj y i. El primer argumento será el nombre de instancia de la esfera que queremos modificar la posición, el segundo, i será la variable de iteración para operaciones posteriores.

En primer lugar, la función place_obj realiza un cálculo para situar la esfera dependiendo de su posición inicial. La constante incr_angle es el numero de grados que separa una esfera de otra, si multiplicamos esta constante por el argumento i la posición de “esfera0” será 0 grados, de “esfera1” seria 1 * 360/numero de objetos, de “esfera2” seria 2 * 360/numero de objetos… Si a estas posiciones fijas le sumamos la variación del angulo que hemos calculado antes estaremos creando el movimiento que buscamos.

Una vez tenemos esto tenemos que pasar este angulo a radianes como se explica en el artículo Movimiento rotativo. Y mediante las formulas Sin y Cos, actualizar el movimiento circular. En este caso hay un par de peculiaridades respecto al artículo Movimiento rotativo, como comentamos al principio del artículo, flash tiene un sistema de coordenadas un poco diferente, por tanto, debemos sumar las variables xo y yo a las posiciones _x e _y respectivamente para centrar el movimiento. Por otra parte, en el movimiento circular utilizábamos una variable radio que multiplicábamos a las funciones Sin y Cos, pues para hacer una movimiento elíptico tenemos que multiplicar la función Coseno por la amplitud (amp_x) y la función Seno por la altura (amp_y).

 



Por último y para terminar, las últimas dos líneas son efectos para crear sensación de profundidad. En primer lugar, utilizamos la función scale para escalar los objetos y que cuando más lejos este más pequeños sean. Y después utilizamos la función swapDepths para cambiar el nivel de cada objeto y que no se superpongan los objetos más lejanos a los más cercanos. En ambas utilizamos la posición de la esfera respecto a y porque en nuestro caso cuando más arriba más lejos esta, pero si queremos que nuestro movimiento sea contrario solo debemos poner dos signos negativos.

 


thisObj._y = yo + amp_y * Math.sin(angulo_rad);
// Escalamos las esferas efecto profundidad
thisObj._yscale = thisObj._xscale = - ( thisObj._y - 100 ) * 0.7 + 100;
// Asignamos nuevos niveles para que no se superpongan
thisObj.swapDepths( - thisObj._y );
}

 



Descarga los ejemlos:

Descarga el archivo fla preparado.

Descarga los Ejemplos del articulo

Descarga los Ejemplos avanzados del articulo

COMENTARIOS


[No hay comentarios]


Deja un comentario

Los comentarios no pueden contener ninguna etiqueta xhtml.


Valoración del articulo: 0 1 2 3 4 5


DEBES ESTAR REGISTRADO PARA ENVIAR COMENTARIOS
REGISTRATE!

MANUALES REFERIDOS AL MISMO TEMA

Manual de Mootools.


ARTICULOS REFERIDOS A LA MISMA CATEGORIA

Menu giratorio con efectos 3D.

Movimiento rotativo - Trigonometría.

Menu efecto zoom, escalado al estilo Mac..

Inauguramos la categoria Mootools..

Efecto reflejo en imágenes con javascript y HTML.

Descripción de funciones y eventos de Mootools.



SCRIPTS CLASIFICADOS

Mootools.

Complementos para Photoshop.


PROGRAMAS PARA EL DESARROLLO DE FLASH

Swift 3D - Efectos 3D e importación a Flash.

Macromedia Studio 8 - Dreamweaver 8, Flash 8 ....

Adobe Flash CS3.

Adobe Dreamweaver CS3.


LECTURA RECOMENDADA

Google adds Google adds Google adds Google adds