estoy empezando con as3 y crear clases. de as3 tengo poca idea y de clases la teoría por encima
me sería de mucha ayuda ver cómo puedo construir una clase a partir del siguiente script, para aplicar una máscara animada a cualquier MovieClip q la instancie
miré algun tutorial pero aún estoy muy verde y me atasco en mil cosas
bueno, si a alguien no le cuesta mucho q me pueda echar una mano, muchas gracias
este es el script ( sé q podría estar mejor hecho ):
Código :
import fl.transitions.*;
import fl.transitions.easing.*;
stage.frameRate=9660;
var i:uint = 0;
var maskContainer:Sprite = new Sprite();
bg.mask=maskContainer;
addChild(maskContainer);
var timer:Timer=new Timer(125,0);
timer.addEventListener(TimerEvent.TIMER, animaMask);
timer.start();
function animaMask(event:TimerEvent){
if ( i<= bg.width/ 50 ){
var posx:Number= 50*i;
var posy:Number= bg.y;
i = i+1;
var newMask:MovieClip = new MovieClip();
newMask.graphics.beginFill(0xFFFFFF);
newMask.graphics.drawRect(0,0,50,1);
newMask.graphics.endFill();
maskContainer.addChild(newMask);
newMask.x = posx;
var mover:Tween = new Tween(newMask,"height",Regular.easeOut, newMask.height, 400,1, true);
}
}
bg es un movieClip creado en el stage q ocupa todo el area del flash, pero tendría q ser aplicable a cualquier movieClip por eso quiero convertirlo en clase
o ando tan desorientado q la peña ya ni se molesta o es q tengo más morro q pitorro el caso es q no contesta ni diola, así q me puse a airear neuronas casi y no veas lo q se aprende de camino
la cosa era hacer una máscara con animación de cortinilla, y poderlo aplicar a cualquier MovieClip del escenario y tras darle unas vueltas mirando cosas y aclarando conceptos lo fuí consiguiendo y ya rula
el script queda así
Código :
import fl.transitions.*;
import fl.transitions.easing.*;
stage.frameRate = 60;
var mascara:Sprite;
var elemento:MovieClip = new MovieClip();
var tempo:Timer;
var intervalo:uint = 10;
var i:uint;
var persianaParte:MovieClip;
var persianaParteTamaño:Number = 10;
var tweenTipo:Function= Bounce.easeOut;
var tweenVelocidad:uint = 1;
function iniciarMascara( elem:MovieClip )
{
elemento = elem;
if ( mascara )
{
removeChild( mascara );
mascara = new Sprite();
}
else
{
mascara = new Sprite();
}
aplicarMascara( elemento, mascara );
}
function aplicarMascara( elem:MovieClip, masc:Sprite )
{
i = 0;
mascara = masc;
elemento = elem;
elemento.mask = mascara;
addChild( mascara );
tempo = new Timer( intervalo,0 );
tempo.addEventListener( TimerEvent.TIMER, animarMascaraPersiana );
tempo.start();
}
function animarMascaraPersiana( event:TimerEvent )
{
if ( i <= Math.ceil( elemento.height/persianaParteTamaño ) )
{
var posx:Number = elemento.x;
var posy:Number = elemento.y + persianaParteTamaño * i;
i = i+1;
crearMascaraPersianaParte();
persianaParte.x = posx;
persianaParte.y = posy;
var mover:Tween = new Tween( persianaParte, "height", tweenTipo, persianaParte.height, persianaParteTamaño, tweenVelocidad, true );
}
else
{
tempo.stop();
i = 0;
}
}
function crearMascaraPersianaParte()
{
persianaParte = new MovieClip();
persianaParte.graphics.beginFill( 0xFFFFFF );
persianaParte.graphics.drawRect( 0, 0, elemento.width, 1 );
persianaParte.graphics.endFill();
mascara.addChild( persianaParte );
}
// ahora se puede aplicar la mascara de persiana animada a cualquier MovieClip pasándoselo por parametro a la función iniciarMascara( elem:MovieClip )
iniciarMascara( miElemento );
// y añadiendo un botón y algo más, se aplica con un evento e ratón
/*
function iniciarMascaraConEvento ( e:MouseEvent )
{
iniciarMascara( miElemento );
}
bt.addEventListener ( MouseEvent.CLICK, iniciarMascaraConEvento );
*/
si alguien lo depura, mejora o simplifica q lo comente, q será de mucha ayuda. y se admiten sujerencias para convertirlo en class
de hecho a veces, no se pq´el tween en bucle, se queda atascado y no se completa cada tween. recargar la cortina unas cuantas veces y lo vereis, si no se atasca ya a la primera
el resultado del script es éste
- el swf q puse antes era distinto, pero lo machaque en mi servedor y como la url era la misma, pues ahora se ve lo mismo q en éste último q puse, pero antes no lo aplicaba al MovieClip q quisiera pasándolo por parámetro -
ahora queda pasarlo a class, q mola máss y si eso pues lo pongo en un tip q sería el primero q me curtiese vaya.. uno q es un poco torrón y aún se entorronó más en las últimas primaveras
100, si casi lo tienes. Falta encerrarlo en un package y crear la clase constructora Llamamemos a nuestra clase MascaraPersiana
Código ActionScript :
package{
//nuestra definición de la Clase MascaraPersiana
public class MascaraPersiana {
//Definimos aquí las variables necesarias
//(Las que tenías) y las ponemos "privadas"
private var mascara:Sprite;
private var elemento:MovieClip; //¡¡OJO!! no creamos un MovieClip = new MovieClip();
private var tempo:Timer;
private var intervalo:uint = 10;
private var i:uint;
private var persianaParte:MovieClip;
private var persianaParteTamaño:Number = 10;
private var tweenTipo:Function= Bounce.easeOut;
private var tweenVelocidad:uint = 1;
//creramos la función constructora. Que ha de tener el mismo nombre que la clase
public function MascaraPersiana(elem:MovieClip){
//aquí simplemente llamaremos a la "función iniciarMascara"
iniciarMascara( elem:MovieClip )
}
....aquí escribimos todo tu código
}
}
Vale, todavía NO va a funcionar, pues hay que hacerle un pequeño cambio 1.-Debemos añadir "mascara" a elemento.parent Además, por mejorarlo: 2.-Si tenemos elementos gráficos sin línea de tiempo, lo suyo es hacer unos "Sprite", en lugar de MovieClips (vamos, que "persianaParte" debería ser un Sprite, no un MovieClip 3.-Toda vez que el resultado final es que se vea la imagen, al acabar el tween podríamos removeChild la persiana e igualar a null la propiedad mask de elemento 4.-solucionar el problema de que se atasque el bucle. En general es mala idea llamar a tweens con un Timer o tener muchos tweens. ¿por qué no te creas todas las "persianas parte" y creas un único tween que anime todas?
si, no faltaba mucho pero me aclaró cómo continuar. Y sobre todo las apreciaciones
1 - ta claro, hay q añadir la máscara al elemento.parent ( nivel superior de éste ) aunq aún así, y no sé por q´, no logra encontrar el elemento a enmascarar si es hijo de otro elemento. será la siguiente cuestión si no lo esclarezco
2 - ta claro, objetos Display pesan menos, reducirá sustancialmente el tamaño reservado en memoria y le costará menos su procesamiento, por lo q pude ir enterándome
3 - perfecto. así en caso de q no se complete la animación de la persiana en la máscara, acabará mostrando el elemento enmascarado igualmente. y reducimos peso desde luego ( si tenemos muchos elementos desplegados por con esta cortinilla, acabaría lento lento
4 - me parece acertado, pero cambiaría el efecto de animación, pq la animación no sólo depende del tween. tienen q ir apareciendo las partes o tablillas de la persiana máscara de una manera secuencial, según un intervalo de tiempo q le pasemos, no q aparezcan todas de golpe y se interpolen a lo unísono. el efecto cambia y queda algo menos vistoso. pero guay por la sugerencia. creo q pasar todo a Sprites y eliminar la máscara al final ayudará a q no se atasque durante el proceso
con todo ya pude crear la clase, aunq funciona más o menos por lo q te dije de aplicarla a elementos hijos de elementos
a ver si sabes tu el por q´ a primera vista o es algo sencillo ( elemento:* ). debo q seguir probando
hasta el momento, funcionando para elementos desplegados en la línea de tiempo principal, la clase quedaría así. la dejo comentada hasta la saciedad, para atrofiados como yo. citando a Kraftwerk: 'somos los bobofhs, tun-tan-tin-tin'. puede servirles a los q se inicien en ésto o anden migrando a as3 me enrollo como una persiana
Class PersianaMascara
Código :
package {
// 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
_tempoIntervalo = tempoIntervalo;
_persianaParteTamaño = persianaParteTamaño;
_tweenFuncion = tweenFuncion;
_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 )
elemento.visible = false;
// fijamos contador del numero de partes de persiana a 0
_i = 0;
// asignamos variable por parámetro a la privada declarada del elemento enmascarado
_elemento = elemento;
// si existe ya la mascara, la elimina y crea una instancia Sprite
if ( _mascara ) {
_elemento.parent.removeChild( _mascara );
_mascara = new Sprite();
} else {
_mascara = new Sprite();
}
// aplicamos la máscara al elemento enmascarado
_elemento.mask = _mascara;
// añadimos la máscara al nivel anterior del elemento enmascarado
_elemento.parent.addChild( _mascara );
// hacemos el elemento enmascarado visible
_elemento.visible = true;
// hacemos la instancia al timer y le pasamos la variable de intervalo del tempo
_tempo = new Timer( _tempoIntervalo, 0 );
// añadimos un listener para escuchar el evento del Timer y llame a la función animarPersianaMascara en cada intervalo
_tempo.addEventListener( TimerEvent.TIMER, animarMascaraPersiana );
// iniciamos el la cuenta del Timer
_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( _persianaParte, "height", _tweenFuncion, _persianaParte.height, _persianaParteTamaño, _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 ( _i == Math.ceil( _elemento.height /_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 ( _i <= Math.ceil( _elemento.height/ _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 = _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 = _elemento.y + _persianaParteTamaño * _i;
// incrementa el número de partes/tablillas creadas hasta el momento
_i ++;
// creamos la instancia del Sprite q va a contener la parte/tablilla a añadir
_persianaParte = new Sprite();
// comenzamos el rellenado
_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
_persianaParte.graphics.drawRect( 0, 0, _elemento.width, 1 );
// cierra el relleno
_persianaParte.graphics.endFill();
// lo posicionamos
_persianaParte.x = posx;
_persianaParte.y = posy;
// lo añadimos dentro de la máscara
_mascara.addChild( _persianaParte );
} else {
// en caso de q se supere el número de tablillas para rellener el alto del elemento enmascarado
// paramos el Timer
_tempo.stop();
}
}
private function deshabilitarMascara( event:TweenEvent ) {
// deshabilitamos la máscara aplicada al elemento enmascarado
_elemento.mask = null;
// lo eliminamos del nivel superior al elemento enmascarado
_elemento.parent.removeChild( _mascara );
}
}
}
si hubiera algo repetido o q sobre, o q fuera más apropiado abordarlo de otra manera o en otro orden, sigo al tanto
.....
para aplicar la clase, creamos un documento as3, añadimos un elemento display ( MovieClip, Button, Graphic, .. ) y se lo pasamos a la función constructora junto con otros parámetros
public functionMascaraPersiana( elemento:Sprite, tempoIntervalo:uint, persianaParteTamaño:Number, tweenFuncion:Function, tweenVelocidad:uint );
elemento sería el cualquier objeto display de nuestro display tree
tempoIntervalo sería el retardo del tempo ( delay del objeto Timer ), q determinará el intervalo de tiempo en milisegundos, en q irá creando cada parte ( o tablillas ) de la persiana dentro de la mascara
persianaParteTamaño sería el alto ( height ) en pixeles de cada parte de la persiana dentro de la mascara
tweenFuncion sería el tipo de función ( func del objeto Tween < Regular/Strong/Back/Elastic/Bounce.easeIn/Out/InOut > ) q determinará la forma de animar cada una de las partes de la persiana en la mascara, desde su valor inicial hasta su tamaño de alto final ( persianaParteTamano )
tweenVelocidad sería la duración de la función ( duration del objeto tween ) q determinará la velocidad en q evoluciona la animación de cada una de las partes de la persiana en la mascara, desde su valor inicial hasta su tamaño de alto final ( persianaParteTamano )
añadiendo un botón y un listener a su evento para q llame a una función q instancie el objeto MascaraPersiana podría quedar un ejemplo como éste
probar a cambiar los parámetros para ver como varía el efecto cortina animada en máscara. da su juego para mostrar los objetos de nuestros proyectos, animaciones, ..
.....
el resultado visual sería como lo visto anteriormente
y repito aún no funciona para aplicarlo a elementos hijos de otros elementos, y niveles inferiores mientras busco la solución, se admiten sujerencias
y una vez más, Opa Eliseo!!! gracias tío
si lo pongo en tip te pongo en los créditos
and it's all over now, babysblue
el logo este q pongo es el mío de diseñador/ desarrollador. una pila de base datos con careto