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
