Posicionamento de UI

Defina a posição, escala, padding e outras propriedades de entidades de UI.

Para todos os tipos de conteúdo de UI, use o uiTransform componente para definir o tamanho, posição e outras propriedades relacionadas ao alinhamento da entidade.

O uiTransform componente funciona no espaço 2D da tela muito parecido com o Transform componente funciona no espaço 3D da cena.

arquivo ui.tsx:

import { UiEntity, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'

export const uiMenu = () => (
	<UiEntity
		uiTransform={{
			width: '200px',
			height: '100px',
			justifyContent: 'center',
			alignItems: 'center',
		}}
		uiBackground={{ color: Color4.Green() }}
	/>
)

arquivo index.ts:

import { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
import { uiMenu } from './ui'

export function main() {
    ReactEcsRenderer.setUiRenderer(uiMenu, { virtualWidth: 1920, virtualHeight: 1080 })
}
circle-exclamation

Propriedades de posicionamento

O alinhamento das entidades de UI é baseado no modelo de alinhamento Flexbox. Este é um modelo muito poderoso para organizar dinamicamente entidades aninhadas dentro de modais que podem variar de tamanho.

circle-info

💡 Tip: A implementação de UI do Decentraland é baseada na de Yogaarrow-up-right. Leia este artigoarrow-up-right para uma cobertura acessível e aprofundada das propriedades disponíveis no Flexbox.

Tamanho da entidade

Use width e height para definir o tamanho da entidade. Os seguintes tipos de valores são suportados:

  • auto: O tamanho se adapta para caber no conteúdo interno. Isso é muito conveniente para texto que pode variar em comprimento. Escreva o valor como "auto".

  • Porcentagem: Como uma porcentagem das medidas do pai. Escreva o valor como uma string que termina em "%", por exemplo 10 %.

  • Pixels: Escreva o valor como um número.

  • Largura ou altura da tela: Use vw (view width) e vh (view height) para indicar uma fração do tamanho total da janela onde o Decentraland está sendo executado. Por exemplo 10vw refere-se a 10% da largura da janela, 25vh a 25% da altura da janela.

Observe que essas propriedades afetam o default tamanho desse item, o tamanho do item antes de quaisquer cálculos de flex grow e flex shrink serem realizados. O tamanho final pode ser interpretado de forma diferente com base no tamanho da entidade pai e nas propriedades do Flexbox que estão definidas.

circle-exclamation

Estas outras propriedades também estão disponíveis para ajustar o tamanho de forma mais avançada:

  • maxWidth e maxHeight: maxDistance ou string (como height e width). O tamanho máximo que a entidade pode ter.

  • minWidth e minHeight: maxDistance ou string (como height e width). O tamanho mínimo que a entidade pode ter. Se o pai for muito pequeno para caber o tamanho mínimo das entidades, elas irão transbordar do seu pai.

  • flexBasis: Esta é uma forma independente de eixo de fornecer o tamanho padrão de um item ao longo do eixo principal. Definir o flex basis de um filho é semelhante a definir a largura desse filho se seu pai for um contêiner com flex direction: row ou definir a altura de um filho se seu pai for um contêiner com flex direction: column.

Organizando entidades filhas

Por padrão, as entidades filhas são posicionadas em relação ao canto superior esquerdo de seu pai. Você pode usar propriedades como justifyContent e alignItems para alterar esse comportamento.

circle-info

💡 Tip: Qualquer propriedade que se refira a content refere-se a entidades ao longo do eixo principal (determinado por flexDirection). Qualquer propriedade que se refira

  • flexDirection: Flex direction controla a direção na qual os filhos de um nó são dispostos. Isso também é referido como o eixo principal. O eixo principal é a direção na qual os filhos são dispostos. O eixo cruzado é o eixo perpendicular ao eixo principal, ou o eixo no qual as linhas de quebra são dispostas. Ele obtém seu valor do FlexDirectionType type. As seguintes opções estão disponíveis:

    • row (PADRÃO)

    • row-reverse

    • column

    • column-reverse

  • justifyContent: Esta propriedade descreve como alinhar os filhos dentro do eixo principal do seu contêiner. Por exemplo, você pode usar esta propriedade para centralizar um filho horizontalmente dentro de um contêiner com flexDirection definido como row ou verticalmente dentro de um contêiner com flexDirection definido como column. O valor desta propriedade deve ser do AlignType type. Valores possíveis são:

    • flex-start (PADRÃO): Alinha os filhos de um contêiner ao início do eixo principal do contêiner.

    • flex-end: Alinha os filhos de um contêiner ao fim do eixo principal do contêiner.

    • center: Alinha os filhos de um contêiner no centro do eixo principal do contêiner.

    • space-between: Distribui os filhos de forma uniforme ao longo do eixo principal do contêiner, distribuindo o espaço restante entre os filhos.

    • space-around: Distribui os filhos de forma uniforme ao longo do eixo principal do contêiner, distribuindo o espaço restante ao redor dos filhos. Comparado ao space-between, usar space-around resultará em espaço sendo distribuído no início do primeiro filho e no final do último filho.

  • alignItems: Descreve como alinhar os filhos ao longo do eixo cruzado do seu contêiner. Align items é muito similar a justify content, mas em vez de aplicar ao eixo principal, align items aplica-se ao eixo cruzado. Esta propriedade requer um valor do AlignType type. As seguintes opções estão disponíveis:

    • stretch: (PADRÃO) Estica os filhos de um contêiner para corresponder à altura do eixo cruzado do contêiner.

    • flex-start: Alinha os filhos de um contêiner ao início do eixo cruzado do contêiner.

    • flex-end: Alinha os filhos de um contêiner ao fim do eixo cruzado do contêiner.

    • center: Alinha os filhos de um contêiner no centro do eixo cruzado do contêiner.

    • baseline: Alinha os filhos de um contêiner ao longo de uma linha de base comum. Filhos individuais podem ser definidos como a linha de base de referência para seus pais.

  • alignSelf: Align self tem as mesmas opções e efeito que alignItems mas em vez de afetar os filhos dentro de um contêiner, você pode aplicar esta propriedade a um único filho para alterar seu alinhamento dentro do pai. align self substitui qualquer opção definida pelo pai com align items. Ele obtém seu valor de AlignType, veja alignItems acima para detalhes sobre essas opções.

  • alignContent: Align content define a distribuição das linhas ao longo do eixo cruzado. Isto só tem efeito quando os itens são quebrados em várias linhas usando flexWrap. Ele obtém seu valor do AlignType type. As seguintes opções estão disponíveis:

    • flex-start: (PADRÃO) Alinha as linhas quebradas ao início do eixo cruzado do contêiner.

    • flex-end: Alinha as linhas quebradas ao fim do eixo cruzado do contêiner.

    • stretch: Estica as linhas quebradas para corresponder à altura do eixo cruzado do contêiner.

    • center: Alinha as linhas quebradas no centro do eixo cruzado do contêiner.

    • space-between: Distribui uniformemente as linhas quebradas ao longo do eixo principal do contêiner, distribuindo o espaço restante entre as linhas.

    • space-around: Distribui uniformemente as linhas quebradas ao longo do eixo principal do contêiner, distribuindo o espaço restante ao redor das linhas. Comparado ao space-between, usar space-around resultará em espaço sendo distribuído no início das primeiras linhas e no final da última linha.

  • flexGrow: Isso descreve como qualquer espaço dentro de um contêiner deve ser distribuído entre seus filhos ao longo do eixo principal. Depois de posicionar seus filhos, um contêiner distribuirá qualquer espaço restante de acordo com os valores de flex grow especificados por seus filhos. Flex grow aceita qualquer valor float >= 0, com 0 sendo o valor padrão. Um contêiner distribuirá qualquer espaço restante entre seus filhos ponderado pelo valor de flex grow do filho.

  • flexShrink: Descreve como reduzir (shrink) os filhos ao longo do eixo principal no caso de o tamanho total dos filhos exceder o tamanho do contêiner no eixo principal. flex shrink é muito similar ao flex grow e pode ser pensado da mesma forma se qualquer tamanho excedente for considerado espaço restante negativo. Essas duas propriedades também funcionam bem em conjunto permitindo que os filhos cresçam e encolham conforme necessário. Flex shrink aceita qualquer valor float >= 0, com 1 sendo o valor padrão. Um contêiner encolherá seus filhos ponderado pelo valor de flex shrink do filho.

  • overflow: Determina o que acontece se o tamanho dos filhos de uma entidade exceder seu pai. Ele usa valores do OverflowType Entity

    • hidden: Entidades que excedem ficam invisíveis.

    • visible: Entidades que excedem saem das margens do pai.

  • flexWrap: A propriedade flex wrap é definida em contêineres e controla o que acontece quando os filhos excedem o tamanho do contêiner ao longo do eixo principal. Por padrão, os filhos são forçados a uma única linha (o que pode encolher entidades). Se o wrapping for permitido, os itens serão quebrados em várias linhas ao longo do eixo principal, se necessário. wrap-reverse se comporta da mesma forma, mas a ordem das linhas é invertida. Esta propriedade obtém seu valor de FlexWrapType Entity

    • wrap

    • no-wrap

    • wrap-reverse

Margens e padding

  • margin: Esta propriedade afeta o espaçamento ao redor fora de um nó. Um nó com margin se deslocará em relação aos limites do seu pai, mas também deslocará a localização de quaisquer irmãos. A margem de um nó contribui para o tamanho total de seu pai se o pai tiver tamanho automático. Define o espaçamento entre a entidade e as margens do pai. O valor esperado é um objeto que contém as propriedades top, left, bottom, e right.

  • padding: Esta propriedade afeta o tamanho do nó ao qual é aplicada. Padding em Yoga age como se box-sizing: border-box; estivesse definido. Ou seja, padding não aumentará o tamanho total de uma entidade se ela tiver um tamanho explícito definido. Para nós com tamanho automático, padding aumentará o tamanho do nó e também deslocará a localização de quaisquer filhos. O valor esperado é um objeto que contém as propriedades top, left, bottom, e right.

Ajustar posição finamente

No Flexbox, as posições das entidades são majoritariamente determinadas por como elas são parentadas e quais propriedades de arranjo estão definidas no pai e no filho. Frequentemente você nem precisa definir a propriedade position de todo. Mas se você quiser ajustar isso, ou sobrescrever completamente o fluxo normal do Flexbox e definir uma posição absoluta, aqui estão as propriedades relevantes:

  • positionType: Define como as entidades são posicionadas. Usa um valor do PositionType enum.

    • relative: (PADRÃO) Por padrão uma entidade é posicionada relativamente. Isso significa que a entidade é posicionada de acordo com o fluxo normal do layout e então deslocada relativamente a essa posição com base nos valores de top, right, bottom, e left. O deslocamento não afeta a posição de quaisquer entidades irmãs ou pais.

    • absolute: Quando posicionada absolutamente, uma entidade não participa do fluxo normal do layout. Ela é, em vez disso, posicionada independentemente de seus irmãos. A posição é determinada com base no top, right, bottom, e left valores

  • position: Os valores de posição top, right, bottom, e left se comportam de forma diferente dependendo do positionType. Para uma entidade relativa eles deslocam a posição da entidade na direção especificada. Para uma entidade absoluta, entretanto, essas propriedades especificam o deslocamento do lado da entidade em relação ao mesmo lado no pai. O valor esperado é um objeto que contém as propriedades top, left, bottom, e right.

circle-exclamation

Visibility

  • display: Determina se uma entidade está visível ou não. Para tornar uma entidade invisível, defina display para none.

Z Index

O zIndex propriedade de um UiEntity determina a ordem na qual as entidades são renderizadas. Entidades com um zIndex mais alto são renderizadas acima de entidades com um zIndex. O zIndex padrão é 0.

circle-exclamation

Tamanho de UI responsiva

Jogadores com diferentes tamanhos de tela podem ver seu layout de UI de forma diferente. Se você definir o tamanho de qualquer elemento de UI para um número fixo de pixels, essa UI pode ficar pequena demais para leitura em displays retina, que têm uma densidade de pixels muito maior.

Em vez de posicionar e dimensionar elementos de UI em termos de porcentagens da tela, você também pode obter as dimensões do canvas e então calcular as posições e tamanhos absolutos seguindo sua própria lógica personalizada. Por exemplo, você poderia escolher arranjos de diálogo diferentes dependendo do tamanho da tela.

Para obter informações sobre a dimensão da tela, você pode checar o UiCanvasInformation, que é adicionado por padrão à entidade raiz da cena.

O UiCanvasInformation o componente contém as seguintes informações:

  • height: Altura do canvas em pixels

  • width: Largura do canvas em pixels

  • devicePixelRatio: A razão da resolução em pixels físicos do dispositivo em relação aos pixels no canvas

  • interactableArea: Um BorderRect objeto, detalhando a área designada para os elementos de UI da cena. Este objeto contém valores para top, bottom, left e right, cada um desses é o número de pixels nessa margem da tela que são ocupados pela UI do Explorer.

circle-exclamation

O trecho a seguir calcula continuamente um valor multiplicador baseado no tamanho da tela:

O valor do scaleFactor variável, que esta função atualiza, pode então ser usado como multiplicador em qualquer elemento de UI na cena, incluindo heigh, width e fontSize valores

Algumas outras melhores práticas relacionadas a tamanhos de UI:

  • Se a largura ou altura de qualquer elemento de UI for dinâmica, é bom também usar os maxWidth, minWidth, maxHeight, e minHeight parâmetros para garantir que eles fiquem dentro de valores razoáveis.

  • O tamanho da fonte do texto é relativo a um número fixo de pixels; você deve torná-lo dinâmico para que permaneça legível em displays retina. Veja Tamanho de texto responsivo

Atualizado