Ir para o conteúdo
  • 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

Mensagens Recomendadas

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.

:(

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

:hmm:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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;

;)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
tintim_22

@clera

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

@coxosclassic

na Greensock lib, deverei utilizar o TimeLineLite?

Obg pelas dicas!

:)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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?

:mad:

Obg.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.