Comunidad de diseño web y desarrollo en internet online

Clase con multiples tweens, se atascan a veces

Citar            
MensajeEscrito el 15 May 2009 07:42 pm
Opa peña!

Me curtí una clase con algo de ayuda. Consiste en una clase q aplica una máscara con una animación de persiana ( crea una sucesión de 'tablillas' consecutivas - como una persiana - con el alto a 1px, y con tweens amplío el alto de cada 'tablilla' hasta un tamaño dado )

El caso es q cuando anima cada 'tablilla' a veces se me atasca alguna y no termina su tween. Mayor problema es q tengo un TweenEvent.MOTION_FINISH al tween de la última 'tablilla' y q deshabilite la máscara y borre la cortina

No tengo apenas experiencia en AS3 y tampoco algunos conceptos muy claros

la clase funcionando pero con esos atasques es ésta ( va muy comentada )


Código :


package com.display.mask {
   
   // importamos librerías necesarias
   import flash.display.Sprite;
   import fl.transitions.*;
   import flash.events.TimerEvent;
   import flash.utils.Timer;

   public class MascaraPersiana extends Sprite {
      
      // Sprite q va a funconar como máscara y como contenedor de la persiana animada
      private var _mascara:Sprite;
      // Sprite q queremos enmascarar
      private var _elemento:Sprite;
      // Timer para dar un intervalo de tiempo en la creación de cada parte ( tablilla o unidad ) de la persina animada
      private var _tempo:Timer;
      // intervalo ( delay ) del Timer
      private var _tempoIntervalo:uint;
      // contador para q las partes de la persianas no sobrepase el alto del Sprite enmascarado, según el tamaño de la parte ( unidad o tablilla ) e la persiana
      private var _i:uint;
      // Sprite para las partes ( tablillas ) de la persiana animada
      private var _persianaParte:Sprite;
      // Tween q animará las partes de la persiana animada dentro de la máscara, desde su valor inicial de alto mínimo hasta su alto final
      private var _persianaParteTween:Tween;
      // alto final de las partes de la persiana animada
      private var _persianaParteTamaño:Number;
      // función o func del Tween ( Regular/Strong/Back/Elastic/Bounce .easeIn/Out/InOut ) q determinará la forma en q evolucionará la animación del Tween
      private var _tweenFuncion:Function;
      // velocidad o duration del Tween interpolada en fotogramas, dependiente del frameRate de la linea de tiempo principal
      private var _tweenVelocidad:uint;

      public function MascaraPersiana( elemento:Sprite, tempoIntervalo:uint, persianaParteTamaño:Number, tweenFuncion:Function, tweenVelocidad:uint ) {

         // recogemos las variables por parmetro de función y se las asignamos a las privadas ya declaradas
         this._tempoIntervalo = tempoIntervalo;
         this._persianaParteTamaño = persianaParteTamaño;
         this._tweenFuncion = tweenFuncion;
         this._tweenVelocidad = tweenVelocidad;

         // llama a la función q iniciará y aplicará la máscara
         mascara( elemento );

      }
      private function mascara( elemento:Sprite ) {

         // hacemos invisible el elemento a enascarar ( si no lo está ya )
         if ( elemento.visible == true ){ elemento.visible = false; }
         // fijamos contador del numero de partes de persiana a 0
         this._i = 0;
         // asignamos variable por parámetro a la privada declarada del elemento enmascarado
         this._elemento = elemento;
         
         // crea una instancia Sprite para la máscara

         this._mascara = new Sprite();
         
         // aplicamos la máscara al elemento enmascarado
         this._elemento.mask = this._mascara;
         // añadimos la máscara al nivel anterior del elemento enmascarado
         this._elemento.parent.addChild( this._mascara );
         // hacemos el elemento enmascarado visible
         this._elemento.visible = true;
         
         // hacemos la instancia al timer y le pasamos la variable de intervalo del tempo
         this._tempo = new Timer( this._tempoIntervalo, 0 );
         // añadimos un listener para escuchar el evento del Timer y llame a la función animarPersianaMascara en cada intervalo
         this._tempo.addEventListener( TimerEvent.TIMER, animarMascaraPersiana );
         // iniciamos el la cuenta del Timer
         this._tempo.start();

      }
      private function animarMascaraPersiana( event:TimerEvent ) {

         // llama a la función q creará la secuencia de partes o tablillas de la persiana animada
         crearMascaraPersianaParte();
         
         // hace el tween q animará cada parte o tablilla de la persiana animada, según los parámetros pasados, desde su valor de alto mínimo inicial hasta su valor de alto máximo determinado por persianaParteTamaño, fijando un tipo de función o func ease para la forma de animar, y la velocidad o duration interpolada en frames de la animación
         var _persianaParteTween = new Tween( this._persianaParte, "height", this._tweenFuncion, this._persianaParte.height, this._persianaParteTamaño, this._tweenVelocidad, true );
         // si el contador de partes o tablillas ( numero de tablillas creadas ) es igual al alto del elemento enmascarado dividido por el alto final de la tablilla ( sería el mínimo de partes/tablillas necesarias para ocupar todo el alto del elemento enmascarado )
         if ( this._i == Math.ceil( this._elemento.height /this._persianaParteTamaño ) ) {
            
            // si creó la última tablilla necesaria, lanzamos un evento q escuche si el tween de animación - en éste caso - de la última parte/tablilla creada, llamará a la función q deshabilita y elimina la máscara
            _persianaParteTween.addEventListener( TweenEvent.MOTION_FINISH, deshabilitarMascara );

         }
         
      }
      private function crearMascaraPersianaParte() {
         
         // mientras el número de partes/tablillas q va creando en la máscara, sea menor o igual al numero de tablillas posibles para llenar el alto del elemento enmascarado, seguirá creando partes/ tablillas
         if ( this._i <= Math.ceil( this._elemento.height/ this._persianaParteTamaño ) ) {

            // el valor de posición x de la parte/tablilla q va a crear, será igual a la posición x del elemento enmascarado
            var posx:Number = this._elemento.x;
            // el valor de posición y de la parte/tablilla q va a crear, será igual al tamaño de la parte/tablilla multiplicado por el número de tablillas creadas hasta el momento
            var posy:Number = this._elemento.y + this._persianaParteTamaño * this._i;
            // incrementa el número de partes/tablillas creadas hasta el momento
            this._i ++;

            // creamos la instancia del Sprite q va a contener la parte/tablilla a añadir
            this._persianaParte = new Sprite();
            // comenzamos el rellenado
            this._persianaParte.graphics.beginFill( 0xFFFFFF );
            // hacemos el rectángulo de la parte/tablilla, con un valor de alto inicial mínimo ( 1px ), el largo del elemento enmascarado y en 0,0 para x,y
            this._persianaParte.graphics.drawRect( 0, 0, _elemento.width, 1 );
            // cierra el relleno
            this._persianaParte.graphics.endFill();
            
            // lo posicionamos
            this._persianaParte.x = posx;
            this._persianaParte.y = posy;
            // lo añadimos dentro de la máscara
            this._mascara.addChild( this._persianaParte );
            

         } else {
            
            // en caso de q se supere el número de tablillas para rellener el alto del elemento enmascarado
            // paramos el Timer
            this._tempo.stop();

         }
      }

      private function deshabilitarMascara( event:TweenEvent ) {

         // deshabilitamos la máscara aplicada al elemento enmascarado
         this._elemento.mask = null;
         // lo eliminamos del nivel superior al elemento enmascarado
         this._elemento.parent.removeChild( this._mascara );


      }
   }
}



el ejemplo q usa esta clase podría ser éste:

Código :

import flash.events.TimerEvent;
import flash.utils.Timer;
import fl.transitions.easing.*;
import com.display.mask.MascaraPersiana;

stage.frameRate = 60;

var i:uint;
var tempo:Timer;
var icoActual:uint;
var icoLoader:Loader = new Loader();

var icoArray:Array = new Array ("icofinde", "icoclases", "icorestaurante", "icopuntoocio", "icosocios", "icoinstalaciones", "icotorneos");

i = 0;
icoActual = 0;

tempo = new Timer( 1000, 0 );
tempo.addEventListener( TimerEvent.TIMER, iniciarAnimacion );
tempo.start();

function iniciarAnimacion ( e:TimerEvent )
{
   
   i ++;
   trace(i);
   if ( i%5 == 0 ){
      
      cargarIco();
      
   }
   
   if ( i == 50 )
   {
      
      i = 0;
      
   }
}
function cargarIco()
{   

   icoLoader.load(new URLRequest(icoArray[icoActual]+".swf"));
   icoLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, añadirIco);
   
}

function añadirIco(e:Event):void
{
   if ( ico ){ removeChild(ico);}
   var ico:MovieClip = new MovieClip();
   addChild(ico).name = "ico";
   ico.addChild(icoLoader).name = "icoLoader";
   ico.visible = false;
   ico.x = 0;
   ico.y = 0;
   var icoMasc:MascaraPersiana = new MascaraPersiana( ico, 20, 20, Regular.easeOut, 1 );
   if ( icoActual < icoArray.length-1 )
   {
      
      icoActual ++;
      
   }
   else
   {
      
      icoActual = 0;
      
   }
}


va cargando swf externos a partir de un array, cada 5segundos al intervalo dado por un tween, y al completar cada carga le aplica la clase para mostrarlo

.....

necesito q alguien me oriente de una manera más correcta de hacer esa clase, para q no se me atasquen los tweens, y asegure q llegue a terminar siempre el tween de la última 'tablilla' q dispara el TweenEvent.MOTION_FINISH

GRACIAS de antemano

Por 100

13 de clabLevel



 

FERROR

firefox
Citar            
MensajeEscrito el 15 May 2009 11:39 pm
y los archivos para descargar ( rar )

el ejemplo de antes 'carruselIconos.swf' ( un slideshow básico ), q importa la clase 'MascaraPersiana.as' tal y como está funcionando ahora mismo. Para los swf externos q irá cargando el carrusel, incluir algunos arcivos .swf en ( raíz )/swf/. Y cambiar los nombres del archivo en icoArray dentro del archivo carruselIconos.fla

la clase:
MascaraPersiana.as

el carrusel:
carruselIconos.swf

La clase estaría alojada en com/display/mask/ ( partiendo de raíz: directorio donde se aloje el carruselIconos.swf )
Cambiar en el icoArray de carruselIcono.fla, los nombres de los archivos swf externos q se quieran cargar en el carrusel
Los swf externos se alojarían en una carpeta swf/ ( partiendo de raíz: directorio donde se aloje el carruselIconos.swf )


.....

bueno, si podeis echarle un ojo y a ver cómo mejorarlo para q no se atasquen los tweens de persiana

Gracias de antemano

Por 100

13 de clabLevel



 

FERROR

firefox
Citar            
MensajeEscrito el 16 May 2009 12:11 am
Le di un vistazo con tu primer codigo y no quize meterme con lo que mencionas en el segundo mensaje me parecio engorroso ^^.

Pero asi a primer vistazo veo que usas una variable "_persianaParteTween" para todos tus tweens y ami me a pasado que hago eso y se me traban algunas veces no todas y algunas veces uno y otras veces otro para solucionar esto yo creo un tween para cada objeto puedes probar.


Código ActionScript :

//Creo un MovieClip global exclusivo para dar nombre a mis tweens
var clip_temp:MovieClip=new MovieClip();

//Hago una funcion que creara mi tween y recibe el objeto al cual aplicarle la animaicon
//modificale a tu gusto para que reciba lo que necesites

//La funcion devuelve un int que sera el nombre asignado al tween
public function NewTween(obj:DisplayObject):int{
                var n:int;
      n=Math.random()*1000;
      clip_temp[n]=new Tween("un monton de parametros");
               return n;

}


//La uso de esta manera 
//cacho el nombre para aplicarle listeners
var c:int;
c=NewTween(objeto a mover);
clip_temp[c].addEventListener(TweenEvent.MOTION_FINISH,FinAnimacion);


Espero con eso ya no se te traben los tweens.
Saludos!!

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 16 May 2009 01:11 am
El carrusel funcionando con la clase tal y como está ahora, lo vereis así:
( vereis q algunos tweens de las persiana se atascan y no terminan )




como el carruselIconos.swf y los swf externos ( cargados por load - new URLRequest ) no están incluídos dentro del dominio de Cristalab, va a dar el error 'Error #2044: IOErrorEvent no controlado: text=Error #2035', preveí un eventListener para IOErrorEvent, expone el error en el campo de texto como excepción

Pero podeis verlo en mi servidor

.....


el código tiene modificaciones al ejemplo anterior

Código :

import flash.events.TimerEvent;
import flash.utils.Timer;
import fl.transitions.easing.*;
import com.display.mask.MascaraPersiana;

stage.frameRate = 60;

var txt:TextField = new TextField();
txt.width = 200;
txt.selectable = true;
addChild(txt);

var i:uint;
var tempo:Timer;
var ico:MovieClip;
var icoActual:uint;
var icoDir:String;
var icoLoader:Loader = new Loader();

var icoArray:Array = new Array ("icofinde", "icoclases", "icorestaurante", "icopuntoocio", "icosocios", "icoinstalaciones", "icotorneos");

i = 0;
icoActual = 0;

tempo = new Timer( 1000, 0 );
tempo.addEventListener( TimerEvent.TIMER, iniciarAnimacion );
tempo.start();

function iniciarAnimacion ( e:TimerEvent )
{
   
   i ++;
   txt.text = String(i);
   if ( i%5 == 0 ){
      
      cargarIco();
      
   }
}

function cargarIco()
{   
   
   if ( ico ){ removeChild(ico);}
   icoDir = "swf/" + icoArray[icoActual] + ".swf";
   
   icoLoader.load(new URLRequest(icoDir));
   icoLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, añadirIco);
   icoLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, CLIError);
   
}

function añadirIco(e:Event):void
{

   ico = new MovieClip();
   addChild(ico).name = "ico";
   ico.addChild(icoLoader).name = "icoLoader";
   ico.x = 0;
   ico.y = 0;
   ico.alpha = .75;
   ico.visible = false;
   var icoMasc:MascaraPersiana = new MascaraPersiana( ico, 20, 10, Bounce.easeOut, 1 );
   if ( icoActual < icoArray.length-1 )
   {
      
      icoActual ++;
      
   }
   else
   {
      
      icoActual = 0;
      i = 0;
      
   }
}

function CLIError( event:IOErrorEvent )
{
   
   txt.text = event.text;
   
   
}



una ayudita por favor..?

Por 100

13 de clabLevel



 

FERROR

firefox
Citar            
MensajeEscrito el 26 May 2009 04:51 pm

Angel Roberto escribió:

Le di un vistazo con tu primer codigo y no quize meterme con lo que mencionas en el segundo mensaje me parecio engorroso ^^.

Pero asi a primer vistazo veo que usas una variable "_persianaParteTween" para todos tus tweens y ami me a pasado que hago eso y se me traban algunas veces no todas y algunas veces uno y otras veces otro para solucionar esto yo creo un tween para cada objeto puedes probar.


Código ActionScript :

//Creo un MovieClip global exclusivo para dar nombre a mis tweens
var clip_temp:MovieClip=new MovieClip();

//Hago una funcion que creara mi tween y recibe el objeto al cual aplicarle la animaicon
//modificale a tu gusto para que reciba lo que necesites

//La funcion devuelve un int que sera el nombre asignado al tween
public function NewTween(obj:DisplayObject):int{
                var n:int;
      n=Math.random()*1000;
      clip_temp[n]=new Tween("un monton de parametros");
               return n;

}


//La uso de esta manera 
//cacho el nombre para aplicarle listeners
var c:int;
c=NewTween(objeto a mover);
clip_temp[c].addEventListener(TweenEvent.MOTION_FINISH,FinAnimacion);


Espero con eso ya no se te traben los tweens.
Saludos!!


..........

Opa Angel R! Si señor

Ayuda muy útil. Esencial. De echo era algo q había pensado pero no sabía hacer. Clip[n] para crear referencias al tween o a un mc era algo q no sabía cómo hacer ( trataba de hacer cosas así: eval ( "movie" + n ) = new Tween(), osea mu perdido )

Ahora no se atascan los tweens. Aunq creo tweens para cada tablilla su id es igual para todas lo q supongo lo liaría al hacer referencias a tweens con el mismo nombre

Resuelto. gracias

Supongo q se puede simplificar mucho, me entruño q no veas :lol: , como pa leerlo, pero aquí queda la clase tal y como ya la estoy usando. funcionando sin atasques

Código ActionScript :


package com.display.mask {
   
   import flash.display.Sprite;
   import flash.display.MovieClip;
   import fl.transitions.*;
   import flash.events.TimerEvent;
   import flash.utils.Timer;

   public class MascaraPersiana extends Sprite {
      
      private var _mascara:Sprite;
      private var _elemento:Sprite;
      private var _tempo:Timer;
      private var _tempoIntervalo:uint;
      private var _i:uint;
      private var _persianaParte:Sprite;
      private var _persianaParteTween:MovieClip;
      private var _persianaParteTamaño:Number;
      private var _tweenFuncion:Function;
      private var _tweenVelocidad:uint;

      public function MascaraPersiana( elemento:Sprite, tempoIntervalo:uint, persianaParteTamaño:Number, tweenFuncion:Function, tweenVelocidad:uint ) {

         _tempoIntervalo = tempoIntervalo;
         _persianaParteTamaño = persianaParteTamaño;
         _tweenFuncion = tweenFuncion;
         _tweenVelocidad = tweenVelocidad;

         mascara( elemento );

      }
      private function mascara( elemento:Sprite ) {

         if ( elemento.visible == true ){ elemento.visible = false; }
         _i = 0;
         _elemento = elemento;
         
         _mascara = new Sprite();
         
         _elemento.mask = _mascara;
         _elemento.parent.addChild( _mascara );
         _elemento.visible = true;
         
         _persianaParteTween = new MovieClip();
         _tempo = new Timer( _tempoIntervalo, 0 );
         _tempo.addEventListener( TimerEvent.TIMER, animarMascaraPersiana );
         _tempo.start();

      }
      private function animarMascaraPersiana( event:TimerEvent ) {

         crearMascaraPersianaParte();
         
         _persianaParteTween[_i] = new Tween( _persianaParte, "height", _tweenFuncion, _persianaParte.height, _persianaParteTamaño, _tweenVelocidad, true );
         
         if ( _i == Math.ceil( _elemento.height /_persianaParteTamaño ) ) {
            
            _persianaParteTween[_i].addEventListener( TweenEvent.MOTION_FINISH, deshabilitarMascara );

         }
         
      }
      public function crearMascaraPersianaParte():uint {
         
         if ( _i <= Math.ceil( _elemento.height/ _persianaParteTamaño ) ) {
            
            var posx:Number = _elemento.x;
            var posy:Number = _elemento.y + _persianaParteTamaño * _i;
            _i ++;
            
            _persianaParte = new Sprite();
            _persianaParte.graphics.beginFill( 0xFFFFFF );
            _persianaParte.graphics.drawRect( 0, 0, _elemento.width, 1 );
            _persianaParte.graphics.endFill();
            
            _persianaParte.x = posx;
            _persianaParte.y = posy;
            this._mascara.addChild( _persianaParte );

         } else {
            
            _tempo.stop();

         }
         
         return _i;
         
      }

      private function deshabilitarMascara( event:TweenEvent ) {

         _elemento.mask = null;
         _elemento.parent.removeChild( _mascara );

      }
   }
}



................

Si a alguien le cunde q la use

Gracias Angel Roberto. A cambio curré un avatar tipo el q uso yo, si te mola aki está



ahí tienes los códigos web ( BBcode, previsualizar, .. )

y otra pregunta. sería útil hacer un tip sobre ésta clasilla? puedo hacerlo yo con mi nivel de usuario?
era por devolver favores pq mira q he aprendido cosas durante años en Cristalab y nunca he aportado nada

Por 100

13 de clabLevel



 

FERROR

firefox
Citar            
MensajeEscrito el 26 May 2009 04:58 pm
Y gracias a Eliseo q me echó una mano a la hora de pasar el script a clase

Por 100

13 de clabLevel



 

FERROR

firefox
Citar            
MensajeEscrito el 27 May 2009 03:29 pm
Hola de nuevo!! Gracias por el avatar aqui lo tengo ya puesto XD.

Sobre el tip no soy el indicado en responder ya que nuna e hecho alguno.

Gracias!!

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 28 May 2009 05:06 pm
Jajajja Si señor!!!!! Me llena de honor y satisfacción. Si quieres los originales los tengo
Anduve mirando los pasos a seguir para hacer un tip. lo curtiré con un poco de tiempo

Gracias Angel Roberto y Eliseo

Por 100

13 de clabLevel



 

FERROR

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.