Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

tintim_22

[Resolvido] [AS3] Possicionamento de Images no Stage

Recommended Posts

tintim_22

Boa noite, tenho um ficheiro XML a carregar imagens para dentro de um swf, que serão dispostas no stage num formato de grelha... até aqui tudo bem, consigo colocar a imagens com um aspecto tosco, porem para embelezar a coisa, pretendia que cada imagem aparecesse-se fora para dentro e uma de cada vez no stage, dou como exemplo esta pagina: http://www.danielkusaka.com/v3/#/pt

com poderei fazer algo semelhante?

Obrigado pela ajuda.

:(

Share this post


Link to post
Share on other sites
coxosclassic

boas

mt fixe o site! ;)

para fazeres algo semelhante, podes criar um "efeito" na disposicao das imagens (ou thumbnails) no stage.

qd estas a posicionar as imagens no stage (em grelha),  em vez de fazeres addChild(), guarda as suas posicoes (x e y) num array ou vector, e depois reposicionas as imagens para fora do stage (usando um Math.random(), por ex). de seguida seria so adicionar um tween a cada uma das imagens para as suas posicoes originais...

Acho que seria por ai(+-) que poderias comecar. :)

se te forem surgindo duvidas, vai colocando-as aqui.

cumps,

cc


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

@coxosclassic

Obg pela ajuda, irei criar 1 pequeno script com aquilo que já tenho, criando então o array e fazendo a tal animação e postarei aqui, creio que poderá resolver o meu problema... mas tenho uma outra duvida, como faço para que cada thumb apareça individualmente, uma de cada vez?

Obg pela ajuda.

🤔

Share this post


Link to post
Share on other sites
coxosclassic

sugeria-te que usases um timer para os thumbs irem aparecendo individualmente.

ou em alternativa, usares a lib greensock para fazeres essa animacao (com muito poucas linhas de codigo, consegues fazer essa animacao)

info:

Timer class:

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Timer.html

Greensock lib:

http://www.greensock.com/

se tiveres duvidas apita ;)

cumps,

cc


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

@coxosclassic

boas... esclarece-me uma duvida, é possivel fazer algo do genero:

arrayqqcoisa[index].[qqcoisa] = mcqqcoisa;
arrayqqcoisa[index].[_x] = 100;
arrayqqcoisa[index].[_y] = 200;

isto é possivel?

[sinto-me burro mas não estou a conseguir passar daqui... o arrayqqcoisa é de facto 1 array lol]

Obg.

:wallbash:

Share this post


Link to post
Share on other sites
clera

boas,

assim não é possivel, ou bem que acedes a uma array multi-dimensional: array[0][0]=100;

ou acedes a um objecto dentro da array: MovieClip(array[0]).x=100;

;)

Share this post


Link to post
Share on other sites
tintim_22

@clera

:) Obg. Era mesmo isso que precisava... thanks!

@coxosclassic

na Greensock lib, deverei utilizar o TimeLineLite?

Obg pelas dicas!

:)

Share this post


Link to post
Share on other sites
coxosclassic

basta-te usar a TweenLite...

podes criar um timer e aplicar um tween a cada um dos thumbs, algo tipo:

var index:int = 0;
var timer:Timer = new Timer( 1000, thumbsArray.length);
timer.addEventListener( TimerEvent.Timer, timerHandler );

function timerHandler( e:TimerEvent ):void
{
    TweenLite.to( thumbsArray[ index ], 1, { x:posOriginal[ index ].x, y: posOriginal[ index ].y } );
    index++;
}

espero que ajude

:)


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

@coxosclassic

claro que ajudou, após a minha postagem tinha feito algo parecido ao teu code e já tinha funcionado, de qq maneira obg!

mas agora tenho aqui um problema do qual não estou a perceber o porque de tal estar a acontecer... tenho um array geral de thumbs, multi-dimensional, aproveitando a dica do @clera, arrumava o mc que contem a foto, o x inicial e final bem como o y inicial e final de cada thumb nesse array... ao colocar estes 5 dados no array, e fazendo um addchild de cada thumb ao container, o mesmo aparecia-me no stage no sitio correcto, centrado, todo bonitinho... ao acrescentar as tweens a cada thumb, o container já me aparece +200 (prá ai..) no eixo do x, todo deslocado. o que poderá estar errado?

😡

Obg.

Share this post


Link to post
Share on other sites
coxosclassic

hmmm... desaconselho-te o uso de arrays multidimensionais nesta situacao... arrays com mais de 1 dimensao sao muito uteis em situacoes especificas, fora disso, podem tornar tudo muito complicado.

como eu idealizava, seria criar 2 arrays:

var posFinal:Array = new Array(); // serve para guardar a posicao final dos thumbs
var thumbs:Array = new Array(); // serve para guardar os thumbs

depois no teu codigo de geracao dos thumbs:

var thumb:Thumb // o teu objecto thumb
for( var i:int = 0; i < numThumbs; i++ )
{
    thumb = new Thumb();

    thumbs.push( thumb  ); //crias o teu thumb e guardas no array
    thumb .x = ... // a posicao x FINAL do thumb ( thumb posicionado na grelha )
    thumb .y = ... // a posicao y FINAL do thumb ( thumb posicionado na grelha )
    
    posFinal.push( {x:thumb.x, y:thumb.y} ) //guardas a posicao FINAL do thumb no array

    //a seguir posicionas os thumbs fora do stage
    thumb.x = ... //a posicao x INICIAL do thumb
    thumb.y = ... //a posicao y INICIAL do thumb

    //e adicionas o thumb à display list
    addChild( thumb );

    // o resto do codigo para o thumb.... (event listeners, etc...)
}

no fim seria o mesmo codigo do timer:

var index:int = 0;
var timer:Timer = new Timer( 1000, thumbsArray.length);
timer.addEventListener( TimerEvent.Timer, timerHandler );

function timerHandler( e:TimerEvent ):void
{
    TweenLite.to( thumbs[ index ], 1, { x:posFinal[ index ].x, y: posFinal[ index ].y } );
    index++;
}

Existem provavelmente maneiras mais faceis de fazer isto, mas podes comecar por este exemplo e torna-lo mais simples.


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

;)

@coxosclassic

obg pela ajuda, segui o teu conselho e bani o array multi-dimensional e criei 2 arrays para facilitar-me a vida... no entanto tenho um problema no container_mc.addChild(mcThumb);... passo a explicar, se coloco algo no genero:

mcThumb.x = (my_thumb_width+7)*contX;
mcThumb.y = (my_thumb_height+7)*contY;
container_mc.addChild(mcThumb);

consigo ter a minha grelha com as minha fotos perfeito com um container_mc de tamanho normal tipo 900x400 (por exemplo)... se sigo a tua dica, ou seja guardo o valor de x e y final no array e mando um x e y inicial tipo:

mcThumb.x = 2000;
mcThumb.y = 400;

o que vai acontecer é que passo a ter um container_mc de tamanho 2200x400 o que me lixa o centralizar da minha tabela... há maneira de ultrapassar este pequeno problema?

Share this post


Link to post
Share on other sites
coxosclassic

hmmm

deduzo que à partida so precisas do width para poder centrar a grelha, certo?

se durante a fase de design, defines que a tua grelha tem 4 colunas (por exemplo), já sabes de antemao qual o valor final do width do container_mc.

imagina que cada thumb tem 128px de width (4 * 128 = 512), logo usa esse valor pre-calculado (512) para centrares a grelha no stage, e nao o width do container_mc.

se nao for nada disto avisa.

cumps,

cc


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

CC

boa noite, obrigado pela pronta resposta... o que me está a acontecer é basico... preciso de 1 container de tamanho 941 de width... ao criar as tweens e ao manda-las para x = 2000 (por exemplo), o width do container altera-se para 2941 em x, o que me cria a tabela quase fora do stage na fase do design... tenho 1 função de resize que coloca-me a grelha centrada mas após a fase do design e tenho de alterar a janela de browser... há maneira de calcular a colocação da 1ª thumb no container (no sitio certo) e a partir dai calcular toda a grelha? queres que te envie o meu script?

obg.

Share this post


Link to post
Share on other sites
coxosclassic

ok, acho que estamos a falar da mesma coisa :)

A ordem que estava a sugerir seria a seguinte:

1 - adicionar os thumbs (correctamente posicionados) ao container_mc

2 - posicionar o container_mc (centrar no stage)

3 - espalhar os thumbs para fora do stage

4 - adicionar o container_mc à DisplayList

5 - animar as thumbs para as suas posicoes finais (originais)

Vamos por partes:

Iras de precisar das seguintes variaveis:

var thumbs:Array = []; // array para guardar as thumbs
var finalPos:Array = []; // array para guardar a posicao final das thumbs
var index:int = 0; // contador para percorrer o thumbs durante o timer
var container_mc:Sprite = new Sprite(); // container para as thumbs (grelha)

Se ainda nao tiveres, cria uma função so para a criação da grelha, algo tipo:

function buildGrid():void
{
}

Agora, dentro desta funcao crias todo o processo para gerar a grelha:

function buildGrid():void
{
    var thumb:Thumb // a tua instancia do thumb

    // as seguintes variaveis irao ser usadas para definir a posicao final das thumbs na grelha...
    var columnCounter:int = 0; // contador para o numero de colunas
    var yPos:Number = 0;
    var offset:Number = 5; //distancia entre as thumbs... usa o valor que mais te convem

    // 15 thumbs por exemplo...
    for( var i:int = 0; i < 15; i++ )
    {
         // se para cada linha, o numero de colunas for 4, fazer reset às variaveis de posicao ( muda o numero "4" para o numero de
         //colunas que pretendes ter)
         if( columnCounter == 4 )
         {
             yPos += thumb.height + offset; // baixa para a proxima linha da grelha
             columnCounter = 0; // reset ao contador
         }
         
         thumb = new Thumb();
         thumb.x = (thumb.width + offset) * columnCounter; //posiciona a thumb em x
         thumb.y = yPos; //posiciona a thumb em y

         finalPos.push( {x:thumb.x, y:thumb.y} ); //guarda a posicao final para cada thumb
         thumbs.push( thumb ); // guarda a thumb no array

         container_mc.addChild( thumb ); //adiciona o thumb ao container

         columnCounter++; //incrementa o numero de colunas da grelha
    }

    container_mc.x = (stage.stageWidth / 2) - (container_mc.width / 2); //posiciona a grelha (centrada no stage)

     // ja tens a grelha alinhada, agora podes reposicionar os thumbs para fora da stage
    for each( var t:Thumb in thumbs )
    {
         t.x = 2000; // podes usar o valor que quiseres... desde que fique fora do stage 
    }

    // a grelha e os thumbs estao correctamente alinhados, agora adiciona o teu container_mc a displayList
    addChild( container_mc );

    // cria o timer para a animacao...
    var timer:Timer = new Timer( 200, thumbs.length );
    timer.addEventListener( TimerEvent.TIMER, timerHandler );
    timer.start();
}

E por fim o event handler para a animacao das thumbs:

function timerHandler( e:TimerEvent ):void
{
    TweenLite.to( thumbs[ index ], 1, { x:posFinal[ index ].x, y: posFinal[ index ].y } );
    // podes adicionar mais tweens (alpha por exemplo)
    index++;
}

ao chamares a funcao buildGrid() á partida ficas com a "coisa" feita

O codigo pode ter alguns erros, nao tive tempo de testar, mas o processo seria muito assim.

Se ainda nao te conseguires safar, envia-me entao o script que qd tiver tempo dou uma vista de olhos. ;)

Cumps,

cc


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

é assim que me tenho sentido... eis o meu code

import flash.display.*;
import flash.utils.Timer;
import flash.events.TimerEvent;

import _mc1;

import com.greensock.*;
import com.greensock.easing.*;

var columns:Number;
var my_x:Number;
var my_y:Number;
var my_thumb_width:Number;
var my_thumb_height:Number;
var my_images:XMLList;
var my_total:Number;
var new_x:Number;
var new_y:Number;
var sideX:Number;

var index:int = 0;

var contX:int = 0;
var contY:int = 0;

var container_mc:Sprite;

var arrayThumbs:Array = new Array();
var posFinal:Array = new Array();

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

function construtor():void {

var myXMLLoader:URLLoader = new URLLoader();

myXMLLoader.load(new URLRequest("galeria2.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);

function processXML(e:Event):void {

	var myXML:XML = new XML(e.target.data);

	columns = myXML.@COLUNAS;
	my_x = myXML.@XPOSITION;
	my_y = myXML.@YPOSITION;
	my_thumb_width = myXML.@WIDTH;
	my_thumb_height = myXML.@HEIGHT;
	my_images = myXML.IMAGE;
	my_total = my_images.length();

	createContainer();

	callThumbs();

	stage.addEventListener(Event.RESIZE, resizeHandler); //chama esta função cada vez que o palco é alterado para manter alinhados os quadrados
	stage.dispatchEvent(new Event(Event.RESIZE));

}

function createContainer():void {

	container_mc = new Sprite();

	container_mc.x = my_x;
	container_mc.y = my_y;

}

function callThumbs():void {

	for (var i:Number = 0; i < my_total; i++){

		var mc:_mc1 = new _mc1(my_images[i].@CORFUNDO, my_images[i].@THUMB, my_images[i].@LABEL, my_images[i].@CORFINALLABEL, my_images[i].@TIPO, my_images[i].@CORFINALTIPO);

		mc.name = "mc" + i;

		mc.x = (my_thumb_width+7)*contX;
		mc.y = (my_thumb_height+7)*contY;

		arrayThumbs.push(mc);
		posFinal.push({x:mc.x, y:mc.y});

		container_mc.addChild(mc);

		if (contX+1 < columns) {contX++;
		} else {
			contX = 0;
			contY++;
		}

	}

	container_mc.x = (stage.stageWidth/2) - (container_mc.width/2);
	container_mc.y = 20;

	trace("antes... x: "+container_mc.x);

	for each( var t:_mc1 in arrayThumbs){
		t.x = 200;
		t.y = 400;
   	}

	addChild(container_mc);

	showThumbs();

}

function showThumbs():void {

	var timer:Timer = new Timer(randomNumber(700,1300),arrayThumbs.length);

	timer.addEventListener("timer",timerHandler);
	timer.start();

	function timerHandler(e:TimerEvent):void {
   		TweenLite.to(arrayThumbs[index], 1, {x:posFinal[index].x,y:posFinal[index].y, ease:Expo.easeOut});
   		index++;
		trace("depois... x: "+container_mc.x);
	}

}

function randomNumber(low:Number, high:Number):Number {
	return Math.floor(Math.random() * (1+high-low)) + low;
}

function resizeHandler(e:Event):void {
//função que coloca o quadrado sempre ao meio

	container_mc.x = ((stage.stageWidth / 2) - (container_mc.width / 2));
	container_mc.y = 20;

}

}

construtor();

ora bem, o 1º trace mostra-me a tabela centrada (o valor de x assim o mostra), mas ao colocar as thumbs para fora do stage (simulada aqui com um x a 200 e um y a 400), o 2º trace mostra-me um valor de x duzentas vezes mais, deslocando-o do centro... só volta a ser centrada quando o timer/thumbs acabam e faço um resize ao browser...

já pensei em fazer um container de tamanho 6000, centrado (3000 para cada lado), mas depois como calculo a colocação do 1 thumb?

Obg pela ajuda e pela paciência.

Share this post


Link to post
Share on other sites
coxosclassic

Tens isso tudo a funcionar bem, apenas um pequeno detalhe:

na tua funcao construtor(), tens uma chamada á funcao callThumbs() antes de fazeres o "dispatch" do evento Event.RESIZE...

ou seja, estas a construir e a posicionar bem a grelha, e logo a seguir estas a reposicionar a grelha (com os thumbs afastados). Logo ele estar a colocar (e bem) a grelha fora do sitio :D

A maneira de corrigir isso é simples, basta colocares a funcao callThumbs() logo a seguir ao "dispatch" Event.RESIZE:

function construtor():void {

        var myXMLLoader:URLLoader = new URLLoader();
        
        myXMLLoader.load(new URLRequest("galeria2.xml"));
        myXMLLoader.addEventListener(Event.COMPLETE, processXML);
        
        function processXML(e:Event):void {
                
                var myXML:XML = new XML(e.target.data);
                
                columns = myXML.@COLUNAS;
                my_x = myXML.@XPOSITION;
                my_y = myXML.@YPOSITION;
                my_thumb_width = myXML.@WIDTH;
                my_thumb_height = myXML.@HEIGHT;
                my_images = myXML.IMAGE;
                my_total = my_images.length();
                
                createContainer();
                
                stage.addEventListener(Event.RESIZE, resizeHandler);
                stage.dispatchEvent(new Event(Event.RESIZE));
                
                callThumbs(); //PASSA A FUNCAO PARA AQUI
                
        }
}

desta maneira nao estas a reposicionar a grelha apos a teres criado.

mais uma dica:

deduzo que tenhas criado uma class para o teu _mc1 (thumb ?)

no construtor dessa class estas a passar uma serie de parametros:

var mc:_mc1 = new _mc1(my_images[i].@CORFUNDO, my_images[i].@THUMB, my_images[i].@LABEL, my_images[i].@CORFINALLABEL, my_images[i].@TIPO, my_images[i].@CORFINALTIPO);

sugiro que passes so 1, o my_images (XMLList):

var mc:_mc1 = new _mc1(my_images[i]);

depois no construtor da class, algo tipo:

public function _mc1( data:XMLList ):void {

    _corDeFundo = data..@CORFUNDO;
    _thumb = data.@THUMB;
    _label= data.@LABEL;
    _label= data.@CORFINALLABEL;
    _label= data.@TIPO;
    _label= data.@CORFINALTIPO;

    ...
}

assim o codigo fica mais legivel e um bocado mais simplificado :)

se por acaso nao estiveres a usar nada disto, esquece...  :D

espero que te resolva o prob!

cc


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

;)

cc

obrigado... o "detalhe" da mudança do callThumbs funcionou... mt obrigado, já pensava em mandar todo o script para as urtigas... sim o _mc1 é o thumb, segui a tua dica e no entando deu erro, no genero "TypeError: Error #1034: Falha de coerção de tipo: não é possível converter XML@10cc61a1 element <IMAGE ID="0" THUMB="../style/logo1.jpg"/> em XMLList." lol... de qualquer maneira já ajudaste imenso, muito obrigado.

feliz natal!

Share this post


Link to post
Share on other sites
coxosclassic

Ainda bem que funcionou e que conseguiste perceber o "esquema" ;)

Quanto ao erro que te esta a aparecer, mais uma vez, é um pequeno detalhe. Tal como o erro indica:

"não é possível converter XML@10cc61a1 element <IMAGE ID="0" THUMB="../style/logo1.jpg"/> em XMLList" o contrutor do teu thumb (_mc1) recebe um parametro do tipo XMLList, e estas a enviar um parametro do tipo XML. mais uma vez é bastante simples, muda o tipo XMLList para XML:

public function _mc1( data:XML ):void {

    _corDeFundo = data..@CORFUNDO;
    _thumb = data.@THUMB;
    _label= data.@LABEL;
    _label= data.@CORFINALLABEL;
    _label= data.@TIPO;
    _label= data.@CORFINALTIPO;

    ...
}

e deve funcionar bem assim. :)

alguma duvida apita!

cumps,

cc


Cumps,

cc

Share this post


Link to post
Share on other sites
tintim_22

cc

obrigado pelas dicas e desculpa o trabalho dado...

realmente o detalhe funcionou, obrigando-me a alterar 2 ficheiros .as para 1, já que ambos faziam quase a mm coisa mas para situações distintas, com a tua dica deu para poupar code e juntar tudo num só file, o que eu agradeço.

se tiver duvidas já sei onde postar... obrigado e um bom ano!

Share this post


Link to post
Share on other sites
coxosclassic

Boa!

Ainda bem que conseguiste resolver o teu problema. Mas mais importante, e que tenhas percebido como se faz uma coisa destas. ;)

Vou dar o topico como fechado e coloca-lo como "resolvido".

se tiveres mais alguma duvida, partilha-a

connosco que sempre que der, tentamos ajudar.

cumps.

cc


Cumps,

cc

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.