Effetti di prospettiva 3D per l'interfaccia utente XAML

È possibile applicare effetti 3D ai contenuti nelle app di Windows Runtime usando trasformazioni prospettiche. Ad esempio, è possibile creare l'illusione che un oggetto venga ruotato verso o lontano dall'utente, come illustrato di seguito.

Image with Perspective Transform

Un altro utilizzo comune per le trasformazioni prospettiche consiste nel disporre gli oggetti in relazione tra loro per creare un effetto 3D, come in questo caso.

Stacking objects to create a 3-D effect

Oltre a creare effetti statici 3D, è possibile animare le proprietà della trasformazione prospettica per creare effetti 3D in movimento.

Sono state appena mostrate le trasformazioni prospettiche applicate alle immagini, ma è possibile applicare questi effetti a qualsiasi UIElement, inclusi i controlli. Ad esempio, è possibile applicare un effetto 3D a un intero contenitore di controlli come segue:

3-D effect applied to a container of elements

Ecco il codice XAML usato per creare questo esempio:

<StackPanel Margin="35" Background="Gray">    
    <StackPanel.Projection>        
        <PlaneProjection RotationX="-35" RotationY="-35" RotationZ="15"  />    
    </StackPanel.Projection>    
    <TextBlock Margin="10">Type Something Below</TextBlock>    
    <TextBox Margin="10"></TextBox>    
    <Button Margin="10" Content="Click" Width="100" />
</StackPanel>

Qui ci si concentra sulle proprietà di PlaneProjection che viene usato per ruotare e spostare oggetti nello spazio 3D. L'esempio successivo consente di sperimentare queste proprietà e visualizzare il relativo effetto su un oggetto .

Classe PlaneProjection

È possibile applicare effetti 3D a qualsiasi UIElement impostando la proprietà Projection di UIElement usando PlaneProjection. PlaneProjection definisce la modalità di rendering della trasformazione nello spazio. Nell'esempio seguente viene illustrato un caso semplice.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationX="-35"   />
    </Image.Projection>
</Image>

Questa figura mostra il rendering dell'immagine. L'asse x, l'asse y e l'asse z vengono visualizzati come linee rosse. L'immagine viene ruotata all'indietro di 35 gradi attorno all'asse x usando la proprietà RotationX.

RotateX minus 35 degrees

La proprietà RotationY ruota attorno all'asse y del centro di rotazione.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationY="-35"   />
    </Image.Projection>
</Image>

RotateY minus 35 degrees

La proprietà RotationZ ruota attorno all'asse z del centro di rotazione (una linea perpendicolare al piano dell'oggetto).

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationZ="-45"/>
    </Image.Projection>
</Image>

RotateZ minus 45 degrees

Le proprietà di rotazione possono specificare un valore di rotazione positivo o negativo in entrambe le direzioni. Il numero assoluto può essere maggiore di 360 con l'effetto di ruotare l'oggetto per più di una rotazione completa.

È possibile spostare il centro di rotazione usando le proprietà CenterOfRotationX, CenterOfRotationY e CenterOfRotationZ. Per impostazione predefinita, gli assi di rotazione passano direttamente attraverso il centro dell'oggetto, causando la rotazione dell'oggetto rispetto al suo centro. Se però si sposta il centro di rotazione sul bordo esterno dell'oggetto, questo ruoterà rispetto a tale bordo. I valori predefiniti per CenterOfRotationX e CenterOfRotationY sono 0,5 e il valore predefinito per CenterOfRotationZ è 0. Per CenterOfRotationX e CenterOfRotationY, i valori compresi tra 0 e 1 impostano il punto pivot in una posizione all'interno dell'oggetto. Il valore 0 indica un bordo di un oggetto e 1 indica il bordo opposto. I valori al di fuori di questo intervallo sono ammessi e spostano di conseguenza il centro di rotazione. Poiché l'asse z del centro di rotazione viene disegnato attraverso il piano dell'oggetto, è possibile spostare il centro di rotazione dietro l'oggetto usando un numero negativo e davanti all'oggetto (verso l'utente) usando un numero positivo.

CenterOfRotationX sposta il centro di rotazione lungo l'asse x parallelo all'oggetto, mentre CenterOfRotationY sposta il centro di rotazione lungo l'asse y dell'oggetto. Le illustrazioni successive mostrano l'uso di valori diversi per CenterOfRotationY.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationX="-35" CenterOfRotationY="0.5" />
    </Image.Projection>
</Image>

CenterOfRotationY = "0,5" (impostazione predefinita)

CenterOfRotationY equals 0.5

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationX="-35" CenterOfRotationY="0.1"/>
    </Image.Projection>
</Image>

CenterOfRotationY = "0,1"

CenterOfRotationY equals 0.1

Si noti che l'immagine ruota intorno al centro quando la proprietà CenterOfRotationY è impostata sul valore predefinito 0,5 e ruota vicino al bordo superiore quando è impostata su 0,1. Si noterà un comportamento simile quando si modifica la proprietà CenterOfRotationX per spostare la posizione in cui la proprietà RotationY fa ruotare l'oggetto.

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationY="-35" CenterOfRotationX="0.5" />
    </Image.Projection>
</Image>

CenterOfRotationX = "0,5" (impostazione predefinita)

CenterOfRotationX equals 0.5

<Image Source="kid.png">
    <Image.Projection>
        <PlaneProjection RotationY="-35" CenterOfRotationX="0.5" />
    </Image.Projection>
</Image>

CenterOfRotationX = "0,9" (bordo destro)

CenterOfRotationX equals 0.9

Usare CenterOfRotationZ per posizionare il centro di rotazione sopra o sotto il piano dell'oggetto. In questo modo, è possibile ruotare l'oggetto intorno al punto analogo a un pianeta orbitante intorno a una stella.

Posizionamento di un oggetto

Finora è stato mostrato come ruotare un oggetto nello spazio. È possibile posizionare questi oggetti ruotati nello spazio uno rispetto all'altro usando queste proprietà:

  • LocalOffsetX muove un oggetto lungo l'asse x del piano di un oggetto ruotato.
  • LocalOffsetY muove un oggetto lungo l'asse y del piano di un oggetto ruotato.
  • LocalOffsetZ muove un oggetto lungo l'asse z del piano di un oggetto ruotato.
  • GlobalOffsetX muove un oggetto lungo l'asse x allineato allo schermo.
  • GlobalOffsetY muove un oggetto lungo l'asse y allineato allo schermo.
  • GlobalOffsetZ muove un oggetto lungo l'asse z allineato allo schermo.

Offset locale

Le proprietà LocalOffsetX, LocalOffsetY e LocalOffsetZ traslano un oggetto lungo il rispettivo asse del piano dell'oggetto dopo che questo è stato ruotato. Pertanto, la rotazione dell'oggetto determina la direzione in cui viene traslato l'oggetto stesso. Per illustrare questo concetto, l'esempio successivo anima LocalOffsetX da 0 a 400 e RotationY da 0 a 65 gradi.

Si noti nell'esempio precedente che l'oggetto si sposta lungo il proprio asse x. All'inizio dell'animazione, quando il valore RotationY è vicino a zero (parallelo allo schermo), l'oggetto si sposta lungo lo schermo nella direzione x, ma quando l'oggetto ruota verso l'utente, l'oggetto si sposta lungo l'asse x del piano dell'oggetto verso l'utente. D'altra parte, se la proprietà RotationY è stata animata a -65 gradi, l'oggetto si curva allontanandosi dall'utente.

LocalOffsetY funziona in modo simile a LocalOffsetX, con l'unica differenza che si sposta lungo l'asse verticale. Di conseguenza, la modifica di RotationX influisce sulla direzione in base alla quale LocalOffsetY sposta l'oggetto. Nell'esempio successivo, LocalOffsetY viene animato da 0 a 400 e RotationX da 0 a 65 gradi.

LocalOffsetZ esegue la traslazione dell'oggetto perpendicolarmente al piano dell'oggetto, come se venisse disegnato un vettore partendo direttamente da dietro l'oggetto verso di te attraverso il centro. Per illustrare il funzionamento di LocalOffsetZ, l'esempio successivo anima LocalOffsetZ da 0 a 400 e RotationX da 0 a 65 gradi.

All'inizio dell'animazione, quando il valore di RotationX è vicino a zero (parallelo allo schermo), l'oggetto si sposta direttamente verso l'utente, ma quando il lato dell'oggetto ruota verso il basso, l'oggetto si sposta verso il basso.

Offset globale

Le proprietà GlobalOffsetX, GlobalOffsetY e GlobalOffsetZ traslano l'oggetto lungo gli assi rispetto allo schermo. Ovvero, a differenza delle proprietà di offset locali, l'asse lungo cui l'oggetto si sposta è indipendente da qualsiasi rotazione applicata all'oggetto. Queste proprietà sono utili quando si vuole semplicemente spostare l'oggetto lungo l'asse x, y o z dello schermo senza preoccuparsi della rotazione applicata all'oggetto.

L'esempio successivo anima GlobalOffsetX da 0 a 400 e RotationY da 0 a 65 gradi.

Si noti che in questo esempio l'oggetto non cambia corso durante la rotazione. Ciò è dovuto al fatto che l'oggetto viene spostato lungo l'asse x dello schermo senza considerare la rotazione.

Scenari semi-3D più complessi

È possibile usare i tipi Matrix3DProjection e Matrix3D per scenari semi-3D più complessi di quanto sia possibile con PlaneProjection. Matrix3DProjection offre una matrice di trasformazione 3D completa da applicare a qualsiasi UIElement, in modo da poter applicare matrici di trasformazione di modelli arbitrari e matrici prospettiche agli elementi. Tenere presente che queste API sono minimalistiche e pertanto, se usate, è necessario scrivere il codice che crei correttamente le matrici di trasformazione 3D. Per questo motivo, per semplici scenari 3D, è più facile usare PlaneProjection.