Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Elementi di grafica con XAML

Definire e colorare figure, dal semplice rettangolo alle forme più complesse
Definire e colorare figure, dal semplice rettangolo alle forme più complesse
Link copiato negli appunti

In un articolo precedente abbiamo visto come installare Silverlight e far girare un primo semplice progetto. In questo articolo cerchiamo di approfondire ancora dedicandoci alla realizzazione di elementi grafici.

Cominciamo considerando l'elemento Canvas, ovvero la "tela" sulla quale posizioniamo grafica e testi. Canvas fornisce il più classico dei sistemi di coordinate per la collocazione degli oggetti: possiamo assegnare ad ogni elemento gli attributi:

  • Canvas.Left: distanza dal lato sinistro dell'area Canvas
  • Canvas.Top: distanza dal lato superiore dell'area Canvas
Figura 1. Sistema di coordinate
Sistema di coordinate

È anche possibile annidare più elementi canvas e posizionarli uno dentro l'altro.

Canvas annidati

<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Canvas Height="50" Width="50" Canvas.Left="30" Canvas.Top="30" Background="blue"/>
  <Canvas Height="50" Width="50" Canvas.Left="130" Canvas.Top="30" Background="red"/>

</Canvas>

Disegnare figure piane vettoriali

È possibile disegnare sulla tela di Silverlight utilizzando elementi di grafica vettoriale: in grafica vettoriale un'immagine è descritta attraverso un insieme di punti (vettori) e formule matematiche in maniera tale che possa essere modificata, ingrandita, spostata senza alcun deterioramento. Questo a differenza delle immagini dette "raster" (ad esempio le foto) che sono rappresentate da mappe di pixel.

Abbiamo a disposizione alcuni elementi per definire le figure fondamentali:

Definire le figure di base

<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Ellipse Height="200" Width="200" Canvas.Left="30" Canvas.Top="30"
        Stroke="Black" StrokeThickness="10" Fill="yellow"/>

  <Rectangle Height="100" Width="100" Canvas.Left="5" Canvas.Top="5"
        Stroke="Black" StrokeThickness="10" Fill="yellow"/>

  <Line X1="280" Y1="10" X2="10" Y2="280"
        Stroke="black" StrokeThickness="5"/>

</Canvas>

Figura 2. Le classiche forme
Le classiche forme
  • <Ellipse>: elisse. Ne possiamo definire le dimensioni, in termini di ampiezza del diametro verticale ed orizzontale, o attraverso gli attributi Height ed Width (ovviamente se assegnamo lo stesso valore ai due parametri otteniamo un cerchio).
  • <Rectangle>: rettangolo, anche con gli angoli arrotondati, programmati attraverso RadiusX e RadiusY.
  • <Line>: per disegnare una linea è necessario fissare un punto di partenza con le coordinate x1 e y1 sino a concludere con le coordinate x2 e y2.

È possibile anche disegnare figure più complesse:

Poligoni e spezzate

<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

 <Polyline Points="150,150 100,250 250,200 250,150"
   Stroke="Black" StrokeThickness="10"/>

 <Polygon Points="10,10 10,110 110,110 140,60 200,10"
   Stroke="Black" StrokeThickness="10" Fill="yellow"/>

</Canvas>

Figura 3. Poligono e spezzata
Poligono e spezzata
  • <Polyline>: linea spezzata, è una figura geometrica composta da diversi segmenti collegati tra loro. È considerata una linea aperta e non è possibile colorarne l'area. I vertici sono definiti utilizzando l'attributo Points ed inserendo le coppie di coordinate separate da spazi (x1,y1 x2,y2 ... xn,yn).
  • <Poligon>: come suggerisce il nome, consente di creare un poligono, indicandone i punti come coppie di coordinate separate da spazi. Il poligono è una forma chiusa, quindi possiamo colorarne l'area.

Esempio di curva complessa

<Path Data="M 10,150 C 110,300 210,0 310,150" Stroke="Black" StrokeThickness="3" Fill="yellow"/>

Figura 4. Curva complessa
Curva complessa
  • <Path> ci consente di disegnare figure geometriche piane complesse, come archi o "Curve di Bézier" utilizzando l'attributo Data.

Nell'attributo "Data" possiamo definire e concatenare moltissimi tipi di segmenti e forme, con una sorta di mini-linguaggio. Nel caso mostrato abbiamo definito il punto iniziale con la lettera 'M', che sta per "Move to" ovvero "assumi la posizione...", poi abbiamo fatto sviluppare una curva di Bézier cubica, utilizzando la lettera 'C' (per facilitare la comprensione abbiamo evidenziato i punti di controllo).

Possiamo trovare tutte le opzioni di <Path> su msdn.

Trasformazioni delle figure

Come ci si può aspettare sono applicabili le classiche manipolazioni quali rotazioni, traslazioni, ingrandimenti e riduzioni. Con XAML possiamo definire tutto nell'elemento RenderTransform, al quale indichiamo il tipo e i parametri della trasformazione con semplici elementi figli.

Elemento Descrizione Esempio
RotateTransform rotazione
Ruota una figura di un dato numero di gradi

<Rectangle.RenderTransform>
  <RotateTransform Angle="45"/>
</Rectangle.RenderTransform>
SkewTransform skew
Deforma l'immagine spostando i lati del rettangolo circoscritto. Può dare un effetto assonometrico o prospettico

<Rectangle.RenderTransform>
  <SkewTransform AngleX="30"/>
</Rectangle.RenderTransform>
ScaleTransform skew
Ingradisce o riduce una figura vettoriale

<Rectangle.RenderTransform>
  <ScaleTransform ScaleX="1.3" ScaleY=".5"/>
</Rectangle.RenderTransform>
TranslateTransform translate
Sposta una figura sul Canvas

<Rectangle.RenderTransform>
  <TranslateTransform X="5" Y="2"/>
</Rectangle.RenderTransform>

È pure possibile applicare più trasformazioni in una volta, utilizzando la proprietà TransformGroup

Più trasformazioni insieme

<Rectangle.RenderTransform>
  <TransformGroup>
    <RotateTransform Angle="45"/>
    <ScaleTransform ScaleX=".5" ScaleY="1.2"/>
    <SkewTransform AngleX="30"/>
  </TransformGroup>
</Rectangle.RenderTransform>

Riempimenti

Come abbiamo accennato possiamo colorare l'area ricoperta dalle figure, per impostare il colore di riempimento utilizziamo l'attributo Fill. Inoltre possiamo tracciare il perimetro dell'oggetto, impostando il colore della linea con l'attributo stroke e lo spessore con l'attributo StrokeThickness.

Figura 5. Fill e Stroke
Fill e Stroke: riempimento e perimetro

Possiamo elaborare i nostri riempimenti anche utilizzando i "pennelli". Esistono diversi tipi di marcatori "brush" (pennello appunto), ciascuno con una particolare funzionalità, ne esaminiamo alcuni.

Il più semplice è SolidColorBrush, con il quale otteniamo il riempimento con colore solido, ovvero senza sfumature.

Riempimento solido

<Ellipse.Fill>
  <SolidColorBrush Color="Black" />
</Ellipse.Fill>

Risulta sicuramente più interessante poter sfumare da un colore verso l'altro. Per farlo esaminiamo altri due marcatori: LinearGradientBrush e RadialGradientBrush.

LinearGradientBrush

Serve per ottenere una sfumatura, tra diversi colori, sviluppata su una linea diagonale. Inseriamo i colori che fanno parte della sfumatura utilizzando il l'elemento <GradientStop>. L'attributo offset prende valori su una scala da 0 a 1 e ci consente di stabilire il punto preciso in cui il gradiente si sofferma sul colore indicato.

Per orientare l'inclinazione della linea sulla quale sfuma il colore, utilizziamo le proprietà StartPoint e EndPoint di LinearGradientBrush e definiamo le coordinate di partenza e di arrivo della linea: anche questi parametri sono coefficienti che assumono valori tra 0 e 1.

Figura 6. Parametri della sfumatura lineare
Parametri della sfumatura lineare

Riempimento con sfumatura lineare

<Rectangle Width="140" Height="70" Canvas.Left="10" Canvas.Top="10" >
  <Rectangle.Fill>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <GradientStop Offset="0.50" Color="Yellow" />
      <GradientStop Offset="0.0" Color="Red" />
      <GradientStop Offset="1.0" Color="LimeGreen"/>
    </LinearGradientBrush>
  </Rectangle.Fill>
</Rectangle>

RadialGradientBrush

I colori in questo caso sfumano attraverso un irraggiamento circolare che è impostato attraverso le proprietà GradientOrigin dal quale partono le sfumature e Center, RadiusX, e RadiusY che determinano le dimensioni del cerchio o dell'ellissi.

Figura 7. Parametri della sfumatura radiale
Parametri della sfumatura radiale

Riempimento con sfumatura radiale

<Rectangle Width="140" Height="140" Canvas.Left="155" Canvas.Top="110">
  <Rectangle.Fill>
    <RadialGradientBrush GradientOrigin="0.8,0.8" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5" >
      <GradientStop Offset="0.0" Color="Red" />
      <GradientStop Offset="0.5" Color="Yellow" />
      <GradientStop Offset="1.0" Color="LimeGreen"/>
    </RadialGradientBrush>
  </Rectangle.Fill>
</Rectangle>

Applicare gradienti al testo

È possibile applicare anche al testo riempimenti particolari come dei gradienti. Per farlo utilizziamo la proprietà Foreground.

Testo con gradiente

<TextBlock Canvas.Top="20" Canvas.Left="20"
      FontSize="40" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold">

  Hello world!

  <TextBlock.Foreground>
    <LinearGradientBrush>
      <GradientStop Offset="0.0" Color="Red" />
      <GradientStop Offset="0.5" Color="Yellow" />
      <GradientStop Offset="1.0" Color="LimeGreen"/>
    </LinearGradientBrush>
  </TextBlock.Foreground>
</TextBlock>

Maschere di clipping e trasparenza

La manipolazione delle figure con XAML è molto potente e consente di definire elementi semplici ma anche di modificarli in modo avanzato. Esaminiamo alcune delle applicazioni possibili.

Possiamo voler definire una figura ma visualizzarne solo una porzione, in questo caso possiamo descrivere una maschera di clipping, ovvero un'area di ritaglio, semplicemente definendo al suo interno una ulteriore forma. Ad esempio se vogliamo disegnare solo uno spicchio di un disco possiamo definire l'ellissi e ritagliarla con un rettangolo.

Figura 8. Maschera di clipping
Maschera di clipping

Esempio di Clipping

<Ellipse Stroke="Black" StrokeThickness="10" Fill="Yellow" Height="200" Width="200" Canvas.Left="30" Canvas.Top="30">
  <Ellipse.Clip>
    <RectangleGeometry Rect="0, 0, 100, 100"/>
  </Ellipse.Clip>
</Ellipse>

Inoltre è possibile definire la trasparenza, o l'opacità di un oggetto. Ci serviamo dell'attributo Opacity che può essere impostato su valori nell'intervallo tra 0.0 a 1.0, dove 0 determina la totale trasparenza della figura mentre 1 la rende completamente opaca.

Esempio di rettangolo semitrasparente

<Rectangle Opacity="0.5" Height="100" Width="100" Canvas.Left="30" Canvas.Top="30"/>

È possibile impostare anche maschere per determinare le trasparenze. Utilizzando l'elemento OpacityMask, ad esempio, possiamo impostare la progressiva comparsa di un elemento dell'interfaccia utente.

Figura 8. Maschera di trasparenza
Maschera di clipping

Esempio di uso di OpacityMask

<Ellipse Stroke="Black" StrokeThickness="10" Fill="Yellow" Height="200" Width="200" Canvas.Left="30" Canvas.Top="30">
  <Ellipse.OpacityMask>
    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
      <GradientStop Color="#ff000000" Offset="0"/>
      <GradientStop Color="#00000000" Offset="0.8"/>
    </LinearGradientBrush>
  </Ellipse.OpacityMask>
</Ellipse>

La codifica usata per i colori in questo caso prevede 8 cifre esadecimali invece delle classiche 6, le prime due sono riservate alla rappresentazione dell'indice di opacità.

Immagini ed elementi multimediali

Tra le caratteristiche più potenti di XAML c'è la gestione di contenuti multimediali. È possibile inserire video e audio, utilizzando il marcatore <MediaElement>, ed il relativo attributo Source all'interno del consueto Canvas;

Caricare un filmato

<MediaElement Source="filmato.wmv" Width="300" Height="300" />

È possibile alzare o abbassare il volume attraverso l'attributo Volume, (valori tra 0 e 1, predefinito 0.5), o smorzarlo completamente, con l'attributo IsMuted impostato a true.

Un elemento multimediale condivide la scena con tutti gli altri elementi e si possono sovrapporre a grafici, immagini o testi.

Figura 9. Disco trasparente sovrapposto al video
Disco trasparente sovrapposto al video

Un modo interessante per sfruttare un video può essere quello di incastonarlo in altre forme. Possiamo ottenere questo effetto creando un MediaElement e utilizzandolo come pennello. Il marcatore che fa al caso nostro è <VideoBrush>. Basta assegnare alla proprietà SourceName il nome che abbiamo dato al <MediaElement>.

Nel nostro caso facciamo un esempio di un video in un testo, il testo relativo al video viene formattato attraverso il tipico elemento <TextBlock>

Video nel testo

<MediaElement x:Name="myMediaElement" Source="filmato.wmv" Width="300" Height="300"
      Opacity="0" IsMuted="True" />

<TextBlock Canvas.Left="10" Canvas.Top="10"
      FontFamily="Verdana" FontSize="80" FontWeight="Bold">

  HELLO<LineBreak/>WORLD
  
  <TextBlock.Foreground>
    <VideoBrush SourceName="myMediaElement" />
  </TextBlock.Foreground>
</TextBlock>

Figura 10. Video come colore del testo
Video inscritto nel testo

Con il giusto intreccio di marcatori XAML e un po' di JavaScript possiamo realizzare veri e propri player multimediali, con le classiche funzioni PLAY,STOP,PAUSE etc.

Ti consigliamo anche