E ae blz,
Primeiro post da nova era Technocil, o assunto desse post é uma forma simples de posicionar itens ao redor de um círculo ou elipse, é simples curto e bem objetivo e vai abrir caminho pra alguns outros posts com temas relacionados como, animar itens e textos ao redor de circulos.
Antes de mais nada é bom deixar claro que você precisa ter algum conhecimento de Adobe Flex e AS3 para entender os termos e o post em si, mas é óbvio que pra tirar dúvidas é só comentar.
Requisitos:
CasaLib – download – site
Essa biblioteca é muito poderosa e faz um bocado de coisa que eu sinceramente desconheço, só vamos usá-la para facilitar os calculos com a elipse.
Nosso objetivo é posicionar uma lista de itens ao redor de uma elipse de forma dinâmica independente do número de itens ou do tamanho da elipse, algo que gera um resultado assim:
Bom vendo o resultado, vamos ao código:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="{arrangeItens()}">
<mx:Script>
<![CDATA[
import org.casalib.math.geom.Ellipse;
[Bindable] protected var dataProvider:Array = new Array(8);
protected var ellipse:Ellipse;
protected var _width:Number = 120;
protected var _height:Number = 120;
protected function arrangeItens():void
{
//CENTRALIZANDO A ELLIPSE NO STAGE
var __x:Number = width / 2 - _width / 2;
var __y:Number = height / 2 - _height / 2;
//CRIANDO UMA INSTANCIA DE ELLIPSE DA LIB CASA
ellipse = new Ellipse(__x, __y, _width, _height);
if (images != null)
{
var count:int = images.length;
for (var i:int = 0; i < count; i++)
{
//RECUPERANDO A POSICAO X E Y PARA CADA UM DAS IMAGENS DO REPEATER
var coords:Object = ellipse.getPointOfDegree((360 / count) * i);
//POSICIONANDO AS IMAGENS AO REDOR DO CÍRCULO
images[i].x = coords.x - (images[i].width / 2);
images[i].y = coords.y - (images[i].height / 2);
}
}
}
]]>
</mx:Script>
<mx:Repeater id="rep" dataProvider="{dataProvider}">
<mx:Image id="images" source="@Embed(source='assets/img/item.png')"
width="30" height="30" smoothBitmapContent="true" />
</mx:Repeater>
</mx:Application>
Explicando o que realmente importa no código:
import org.casalib.math.geom.Ellipse;
[Bindable] protected var dataProvider:Array = new Array(8);
protected var ellipse:Ellipse;
protected var _width:Number = 120;
protected var _height:Number = 120;
Nesse trecho o código importa a biblioteca CasaLib, cria um Array de 8 itens só pra servir como dataProvider para o repeater, e define a largura e altura total da elipse.
Vamos ao método que posiciona os itens na tela:
protected function arrangeItens():void
{
//CENTRALIZANDO A ELLIPSE NO STAGE
var __x:Number = width / 2 - _width / 2;
var __y:Number = height / 2 - _height / 2;
//CRIANDO UMA INSTANCIA DE ELLIPSE DA LIB CASA
ellipse = new Ellipse(__x, __y, _width, _height);
if (images != null)
{
var count:int = images.length;
for (var i:int = 0; i < count; i++)
{
//RECUPERANDO A POSICAO X E Y PARA CADA UM DAS IMAGENS DO REPEATER
var coords:Object = ellipse.getPointOfDegree((360 / count) * i);
//POSICIONANDO AS IMAGENS AO REDOR DO CÍRCULO
images[i].x = coords.x - (images[i].width / 2);
images[i].y = coords.y - (images[i].height / 2);
}
}
}
Muito código pouca explicação…
ellipse = new Ellipse(__x, __y, _width, _height);
Primeiro a instancia da elipse criada pela classe não é nada visual, é simplesmente um ponto de referência para posicionar coisas na tela, não confunda achando que vai ver uma elipse na tela só por que instanciou a classe, ela não faz isso.
//RECUPERANDO A POSICAO X E Y PARA CADA UM DAS IMAGENS DO REPEATER
var coords:Object = ellipse.getPointOfDegree((360 / count) * i);
O loop for percorre os itens criados pelo repeater e posiciona cada um em seu específico x e y, que são recuperados pelo método getPointOfDegree da classe Ellipse (o verdadeiro objetivo de todo o post na verdade)
E as linhas abaixo estão corrigindo o posicionamento, anh?… isso mesmo, como o alinhamento base do Flex é no topo a esquerda, fazer algo se alinhar pelo centro pode ser um tanto quanto, trabalhoso (nos próximos posts eu ensino um macete), por isso vamos da uma leve corrigida na posição para os itens não ficarem estranhos.
//POSICIONANDO AS IMAGENS AO REDOR DO CÍRCULO
images[i].x = coords.x - (images[i].width / 2);
images[i].y = coords.y - (images[i].height / 2);
Bom por hoje é só isso, dúvidas é só postar nos comentários.