Profundidade Z e sombra

A gif showing four gray rectangles that are stacked diagonally, one on top of the other. The gif is animated so that shadows appear and disappear.

Criar uma hierarquia visual de elementos torna a interface do usuário fácil de examinar e definir o que é mais importante para se concentrar. A elevação, o ato de trazer os elementos selecionados da interface do usuário para a frente, é geralmente usada para atingir tal hierarquia no software. Este artigo discute como criar elevação em um aplicativo do Windows usando a profundidade Z e sombra.

Profundidade Z é um termo usado entre os criadores de aplicativos 3D para indicar a distância entre duas superfícies ao longo do eixo z. Ela ilustra o quanto um objeto está próximo do visualizador. Imagine-a como um conceito semelhante às coordenadas x/y, mas na direção z.

Os aplicativos do Windows usam sombras para expressar profundidade e adicionar uma hierarquia visual. Para isso, o eixo z fornece um caminho de codificação fácil. Porém, as sombras são emuladas; elas não são exibidas no verdadeiro sentido 3D. Isso é para que possamos obter a sensação de profundidade sem sacrificar o desempenho da interface do usuário do aplicativo.

Por que usar a profundidade Z?

No mundo físico, tendemos a nos concentrar em objetos que estão mais próximos de nós. Também podemos aplicar esse instinto espacial à interface do usuário digital. Por exemplo, se você aproximar um elemento do usuário, ele se concentrará instintivamente no elemento. Ao aproximar os elementos da interface do usuário no eixo z, você pode estabelecer uma hierarquia visual entre os objetos, ajudando os usuários a concluir tarefas de maneira natural e eficiente em seu aplicativo.

O que é sombra?

A sombra é uma maneira de o usuário perceber a elevação. A luz acima de um objeto elevado cria uma sombra na superfície abaixo. Quanto mais alto o objeto, maior e mais suave a sombra se torna. Objetos elevados na sua interface do usuário não precisam ter sombras, mas ajudam a criar a aparência de elevação.

Nos aplicativos do Windows, as sombras devem ser usadas de maneira proposital, e não estética. O uso de muitas sombras diminuirá ou eliminará a capacidade da sombra de focalizar o usuário.

Se você usar controles padrão, as sombras já estarão incorporadas à sua interface do usuário. No entanto, você pode incluir sombras manualmente na interface do usuário usando as APIs ThemeShadow ou DropShadow.

ThemeShadow

O tipo ThemeShadow pode ser aplicado a qualquer elemento XAML para desenhar sombras adequadamente com base nas coordenadas x, y, z.

  • Ele aplica sombras a elementos de acordo com o valor de profundidade z, emulando a profundidade.
  • Ele mantém as sombras consistentes em todos os aplicativos, graças à estética de sombra integrada.

Confira aqui como ThemeShadow foi implementado em um MenuFlyout. MenuFlyout tem uma sombra integrada com uma profundidade de 32px aplicada ao menu principal e a todos os menus aninhados.

A screen shot of ThemeShadow applied to a MenuFlyout with three open, nested menus.

ThemeShadow em controles comuns

Os seguintes controles comuns usarão automaticamente o ThemeShadow para projetar sombras com profundidade de 32 px, a menos que especificado de outra forma:

Observação

ThemeShadow foi introduzido no Windows 10, versão 1903 (SDK 18362). Ele é atualizado no Windows 11 para usar a sombra com nove grades em vez da sombra projetada para melhor desempenho.

ThemeShadow em pop-ups

Geralmente, a interface do usuário do seu aplicativo usa um pop-up para cenários em que você precisa da atenção e ação rápida do usuário. Esses são ótimos exemplos de quando a sombra deve ser usada para ajudar a criar hierarquia na interface do usuário do seu aplicativo.

O ThemeShadow lança sombras automaticamente quando aplicado a qualquer elemento XAML em uma Pop-up. Ele projetará sombras no conteúdo em segundo plano do aplicativo por trás dele e em qualquer outra pop-up aberta abaixo dele.

Para usar o ThemeShadow com pop-ups, use a propriedade Shadow para aplicar um ThemeShadow a um elemento XAML. Em seguida, eleve o elemento de outros elementos por trás dele, por exemplo, usando o componente z da propriedade Translation. Para a maioria das interfaces do usuário pop-up, a elevação padrão recomendada relativa ao conteúdo em segundo plano do aplicativo é de 32 pixels efetivos.

Este exemplo mostra um retângulo em uma pop-up projetando uma sombra no conteúdo em segundo plano do aplicativo e em qualquer outra pop-up por trás dele:

<Popup>
    <Rectangle x:Name="PopupRectangle" Fill="Lavender" Height="48" Width="96">
        <Rectangle.Shadow>
            <ThemeShadow />
        </Rectangle.Shadow>
    </Rectangle>
</Popup>
// Elevate the rectangle by 32px
PopupRectangle.Translation += new Vector3(0, 0, 32);

A single rectangular popup with a shadow.

Desativar o ThemeShadow padrão em controles de submenu personalizados

Controles baseados em Flyout, DatePickerFlyout, MenuFlyout ou TimePickerFlyout usam o ThemeShadow automaticamente para projetar uma sombra.

Se a sombra padrão não parecer correta no conteúdo do seu controle, você poderá desativá-la configurando a propriedade IsDefaultShadowEnabled como false no FlyoutPresenter associado:

<Flyout>
    <Flyout.FlyoutPresenterStyle>
        <Style TargetType="FlyoutPresenter">
            <Setter Property="IsDefaultShadowEnabled" Value="False" />
        </Style>
    </Flyout.FlyoutPresenterStyle>
</Flyout>

ThemeShadow em outros elementos

Observação

Desde o Windows 11, se o aplicativo tiver como alvo o SDK do Windows versão 22000 ou posterior, a coleção Receivers será ignorada. Porém, não haverá erros, e a sombra continuará a funcionar.

Em geral, recomendamos que você pense cuidadosamente na utilização da sombra e limite o uso aos casos em que ela introduz hierarquia visual significativa. No entanto, fornecemos uma maneira de projetar uma sombra de qualquer elemento da interface do usuário, caso você tenha cenários avançados que precisem dela.

Para converter a sombra de um elemento XAML que não esteja em uma pop-up, você deve especificar explicitamente os outros elementos que podem receber a sombra na coleção ThemeShadow.Receivers. Os receptores não podem ser ancestrais do projetor na árvore visual.

Este exemplo mostra dois retângulos que projetam sombras em uma grade atrás deles:

<Grid>
    <Grid.Resources>
        <ThemeShadow x:Name="SharedShadow" />
    </Grid.Resources>

    <Grid x:Name="BackgroundGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />

    <Rectangle x:Name="Rectangle1" Height="100" Width="100" Fill="Turquoise" Shadow="{StaticResource SharedShadow}" />

    <Rectangle x:Name="Rectangle2" Height="100" Width="100" Fill="Turquoise" Shadow="{StaticResource SharedShadow}" />
</Grid>
/// Add BackgroundGrid as a shadow receiver and elevate the casting buttons above it
SharedShadow.Receivers.Add(BackgroundGrid);

Rectangle1.Translation += new Vector3(0, 0, 16);
Rectangle2.Translation += new Vector3(120, 0, 32);

Two turquoise rectangles next to each other, both with shadows.

Sombra

DropShadow não fornece valores de sombra internos, e você precisa especificá-los. Para exemplos de implementações, confira a classe DropShadow.

Dica

Desde o Windows 11, se o aplicativo tiver como alvo o SDK do Windows versão 22000 ou posterior, o ThemeShadow se comportará como uma sombra. Se estiver usando DropShadow, considere o uso de ThemeShadow.

Qual sombra devo usar?

Propriedade ThemeShadow DropShadow
SDK mín SDK 18362 SDK 14393
Capacidade de adaptação Sim Não
Personalização No Sim
Fonte de luz Nenhum Nenhum
Suporte para ambientes 3D Sim (embora funcione em um ambiente 3D, as sombras são emuladas.) Não
  • Lembre-se de que o objetivo da sombra é fornecer uma hierarquia significativa, não como um simples tratamento visual.
  • Em geral, recomendamos o uso de ThemeShadow, que fornece valores de sombra consistentes.
  • Por questões de desempenho, limite o número de sombras, use outro tratamento visual ou use DropShadow.
  • Se você tiver cenários mais avançados para atingir a hierarquia visual, considere usar outro tratamento visual (por exemplo, cor). Se for necessária sombra, use DropShadow.