Programowanie obiektowe i zdarzeniowe wykład 8 grafika i animacja



Podobne dokumenty
Jarosław Kuchta Podstawy Programowania Obiektowego. Podstawy grafiki obiektowej

Budowa aplikacji w technologii.net wykład 11 Animacje

Budowa aplikacji w technologii.net wykład 10 Kształty, pędzle, transformacje, ścieżki

narzędzie Linia. 2. W polu koloru kliknij kolor, którego chcesz użyć. 3. Aby coś narysować, przeciągnij wskaźnikiem w obszarze rysowania.

Podstawy Processingu. Diana Domańska. Uniwersytet Śląski

Laboratorium Programowanie urządzeń mobilnych

Windows Presentation Foundation

4. Rysowanie krzywych

Wizualne systemy programowania. Wykład 11 Grafika. dr Artur Bartoszewski -Wizualne systemy programowania, sem. III- WYKŁAD

CorelDRAW. wprowadzenie

Grażyna Koba. Grafika komputerowa. materiały dodatkowe do podręcznika. Informatyka dla gimnazjum

Księgarnia PWN: Andrzej Jaskulski - AutoCAD 2010/LT Podstawy projektowania parametrycznego i nieparametrycznego

Wprowadzenie do rysowania w 3D. Praca w środowisku 3D

Ćw. I Projektowanie opakowań transportowych cz. 1 Ćwiczenia z Corel DRAW

Spis treści. Część I Przygotowanie środowiska Część II Język C# Wstęp... 9

Dodatek A. Palety. QuarkXPress 4.1. Projekty praktyczne. Podstawowe palety

Kurs Adobe Photoshop Elements 11

WIZUALIZACJA INFORMACJI TEKSTOWEJ WSTĘP DO HTML 5 CANVAS

AUTOCAD teoria i zadania z podstaw rysowania Rysowanie linii, prostej, półprostej, punktu, trasy, polilinii. Zadania geodezyjne.

Adobe InDesign lab.1 Jacek Wiślicki, Paweł Kośla. Spis treści: 1 Podstawy pracy z aplikacją Układ strony... 2.

Wstawianie nowej strony

Przetwarzanie grafiki rastrowej na wektorową

Następnie zdefiniujemy utworzony szkic jako blok, wybieramy zatem jak poniżej

1. Umieść kursor w miejscu, w którym ma być wprowadzony ozdobny napis. 2. Na karcie Wstawianie w grupie Tekst kliknij przycisk WordArt.

Techniki wstawiania tabel

KGGiBM GRAFIKA INŻYNIERSKA Rok III, sem. VI, sem IV SN WILiŚ Rok akademicki 2011/2012

4.3 WITRAś. 1. UŜywając polecenia Linia (_Line) narysować odcinek, podając jako punkt początkowy współrzędną 90,-300 i punkt końcowy 90,55.

Formatowanie komórek

RYSUNEK TECHNICZNY I GEOMETRIA WYKREŚLNA INSTRUKCJA DOM Z DRABINĄ I KOMINEM W 2D

Ćwiczenie 1 Automatyczna animacja ruchu

Wymiarowanie i teksty. Polecenie:

b) Dorysuj na warstwie pierwszej (1) ramkę oraz tabelkę (bez wymiarów) na warstwie piątej (5) według podanego poniżej wzoru:

Programowanie obiektowe i zdarzeniowe wykład 1 Wprowadzenie do programowania zdarzeniowego

WARSTWY cd. Narzędzia służące do transformacji warstw są przedstawione na poniższym rysunku: Służą one odpowiednio do:

XAML Extensible Application Markup Language

Inkscape. Narzędzia informatyki

Spis treści CZĘŚĆ I. NIEPARAMETRYCZNE PROJEKTOWANIE 2D...31

Ćwiczenie 14 Dmuchawce

GIMP Grafika rastrowa (Ćwiczenia cz. 2)

Utworzenie aplikacji mobilnej Po uruchomieniu Visual Studio pokazuje się ekran powitalny. Po lewej stronie odnośniki do otworzenia lub stworzenia

Obsługa programu Paint. mgr Katarzyna Paliwoda

Multimedia i interfejsy. Ćwiczenie 5 HTML5

Szybkie tworzenie grafiki w GcIde

Aby nadać jej pożądaną postać należy w pliku Window1.xaml stworzyć definicję swojego stylu modyfikując ręcznie postać zapisu XAML:

Adobe InDesign rysowanie obiektów wektorowych- przygotowanie pracy

Gramatyki kształtu. 1 Cel zajęć. 2 Narzędzie. 3 Ćwiczenie wprowadzające. 2.1 Uwagi ogólne odnośnie działania

Programowanie telefonów z Windows Phone 7, cz. 5

Tematy lekcji zajęć komputerowych klasa 5b grupa 1 i grupa 2

Zaznaczanie komórek. Zaznaczenie pojedynczej komórki polega na kliknięciu na niej LPM

Rysowanie precyzyjne. Polecenie:

Ćwiczenia - CorelDraw

Praca z Inkscape. 1. Klonowanie obiektów.

Jak uzyskać efekt 3D na zdjęciach z wykorzystaniem programu InkScape

Projektowanie graficzne. Wykład 2. Open Office Draw

Silverlight. Od podstaw

WASM AppInventor Lab 3. Rysowanie i animacja po kanwie PODSTAWY PRACY Z KANWAMI

Podstawy technologii WWW

Narzędzia programu Paint

MODYFIKACJA, EDYCJA OBIEKTÓW W AUTOCADZie Polecenia: SKALA, FAZUJ, ZAOKRĄGL.

Modele zawartości. WPF wykorzystuje 4 modele zawartości kontrolek: ContentControl pojedyncza zawartość

SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE

PyX jest pakietem Pythona do grafiki wektorowej. Pozawala zatem tworzyd pliki EPS oraz PDF.

Animacje cz. 2. Rysujemy koło zębate

Photoshop. Tworzenie tekstu

1. Wprowadzenie do WPF i XAML. Tworzenie interfejsu użytkownika.

GRAFIKA WEKTOROWA. WYKŁAD 1 Wprowadzenie do grafiki wektorowej. Jacek Wiślicki Katedra Informatyki Stosowanej

9. Wymiarowanie. 9.1 Wstęp. 9.2 Opis funkcje wymiarowania. Auto CAD

Ćwiczenie 2 Warstwy i kształty podstawowe

Opis Edytora postaci Logomocji

Autodesk 3D Studio MAX Animacja komputerowa i praca kamery

Obsługa programu Paint materiały szkoleniowe

WSTĘP; NARZĘDZIA DO RYSOWANIA

Wymagania edukacyjne - Informatyka w klasie I

Fragment tekstu zakończony twardym enterem, traktowany przez edytor tekstu jako jedna nierozerwalna całość.

Zastosowania informatyki w geologii ćwiczenia 1,2 INKSCAPE 1

Ćwiczenie 5 Animacja tekstu

Baltie 3. Podręcznik do nauki programowania dla klas I III gimnazjum. Tadeusz Sołtys, Bohumír Soukup

Paweł Kaźmierczak. styczeń 2009

Systemy multimedialne 2015

Inżynieria Materiałowa i Konstrukcja Urządzeń - Projekt

Pasek menu. Ustawienia drukowania

Jarosław Kuchta. Podstawy Programowania Obiektowego. ćwiczenie 10. Podstawy grafiki w WPF

Edytor tekstu OpenOffice Writer Podstawy

CorelDRAW. 1. Rysunek rastrowy a wektorowy. 2. Opis okna programu

Przewodnik po obszarze roboczym

Tworzenie infografik za pomocą narzędzia Canva

O czym należy pamiętać?

PROGRAMOWANIE WINDOWS PRESENTATION FOUNDATION (AVALON) W JĘZYKACH XAML ORAZ C#

Grafika Komputerowa Materiały Laboratoryjne

Kurs Adobe Photoshop Elements 11

Wstęp Pierwsze kroki Pierwszy rysunek Podstawowe obiekty Współrzędne punktów Oglądanie rysunku...

Pascal - grafika. Uruchomienie trybu graficznego. Moduł graph. Domyślny tryb graficzny

PLAN WYNIKOWY KLASA 1

Rozdział VI. Tabele i ich możliwości

Podstawy pozycjonowania CSS

Tworzenie szablonów użytkownika

Edytor tekstu MS Word 2010 PL: grafika. Edytor tekstu MS Word umożliwia wstawianie do dokumentów grafiki.

- biegunowy(kołowy) - kursor wykonuje skok w kierunku tymczasowych linii konstrukcyjnych;

Dodawanie grafiki i obiektów

Transkrypt:

Programowanie obiektowe i zdarzeniowe wykład 8 grafika i animacja Grafika Kształty Najprostszy sposób rysowania własnej zawartości w WPF, to wykorzystanie kształtów. Shapes klasy reprezentujące linie, elipsy, prostokąty, wielokąty (prymitywy, kształty podstawowe). Wszystkie one traktowane są jak elementy: Są zorganizowane w ten sam sposób co inne elementy (umieszczane w kontenerze układu, przeważnie Canvas). Obsługują te same zdarzenia, co inne elementy (a także wspierają tooltipy, menu kontekstowe, etc.). Odpowiadają za rysowanie samych siebie (i automatycznie reagują na zmianę właściwości). Marek Tabędzki 1/62

Klasy kształtów Każdy kształt dziedziczy z abstrakcyjnej klasy System.Windows.Shapes.Shape: Rectangle prostokąt Ellipse elipsa Line odcinek Polyline połączony ciąg odcinków Polygon zamknięty kształt z ciągu połączonych odcinków Path pozwala na łączenie w jednym elemencie wielu innych kształtów Najważniejsze właściwości: Fill pędzel do namalowania zawartości (wnętrza) kształtu Stroke pędzel do namalowania krawędzi kształtu StrokeThickness grubość krawędzi. Jest rozdzielana po równo na obie strony. Marek Tabędzki 2/62

Rectangle, Ellipse Wystarczy zdefiniować rozmiar kształtu (a także Fill lub/i Stroke, aby kształt stał się widoczny): <StackPanel> <Ellipse Fill="Yellow" Stroke="Blue" Height="50" Width="100" Margin="5" HorizontalAlignment="Left"/> <Rectangle Fill="Yellow" Stroke="Blue" Height="50" Width="100" Margin="5" HorizontalAlignment="Left"/> </StackPanel> Marek Tabędzki 3/62

Rectangle dodaje dwie własności: RadiusX i RadiusY (pozwalają na rysowanie zaokrąglonych narożników). <StackPanel> <Rectangle Fill="Yellow" Stroke="Blue" Height="50" Width="100" Margin="5" HorizontalAlignment="Left"/> <Rectangle Fill="Yellow" Stroke="Blue" Height="50" Width="100" Margin="5" HorizontalAlignment="Left" RadiusX="15" RadiusY="15"/> </StackPanel> Marek Tabędzki 4/62

Rozmieszczanie kształtów Przeważnie rozmiar i położenie kształtów określa się ręcznie. Możemy też pozwolić, by kształt dopasował się do dostępnego miejsca: <Grid> <Ellipse Fill="Yellow" Stroke="Blue"></Ellipse> </Grid> Marek Tabędzki 5/62

Określając wartość własności Stretch: Fill dopasowanie wysokości i szerokości do dostępnego miejsca. None bez dopasowania. Uniform dopasowanie proporcjonalne (tak, by kształt mieścił się w kontenerze). Jeśli określimy wysokość i szerokość, będą traktowane jako górne ograniczenie. UniformToFill podobnie, ale każdy z wymiarów ma wypełnić dostępną przestrzeń (część kształtu może zostać ucięta). Marek Tabędzki 6/62

Położenie kształtów jest określane na tych samych zasadach, co innych elementów: rządzi nim kontener. Największą kontrolę nad położeniem daje Canvas: <Canvas> <Ellipse Fill="Yellow" Stroke="Blue" Canvas.Left="100" Canvas.Top="50" Width="100" Height="50"/> <Rectangle Fill="Yellow" Stroke="Blue" Canvas.Left="30" Canvas.Top="40" Width="100" Height="50"/> </Canvas> (uwaga: kolejność definicji ma znaczenie, gdy kształty nakładają się na siebie) (uwaga: Cansa nie musi być elementem najwyższego poziomu możemy umieścić go np. w komórce Grida). Marek Tabędzki 7/62

Viewbox Jest sposobem na połączenie precyzyjnego rozmieszczania kształtów i skalowania do dostępnego rozmiaru. Viewbox to Decorator, przyjmujący pojedyncze dziecko (może nim być kontener z dalszymi elementami), które skaluje, dopasowując do dostępnej przestrzeni. Najbardziej opłacalne w wypadku grupy kształtów: <Grid Margin="5"> <Viewbox Stretch="UniformToFill"> <Canvas Width="50" Height="50"> <Ellipse Fill="Yellow" Stroke="Blue" Canvas.Left="5" Canvas.Top="5" Width="40" Height="40"/> </Canvas> </Viewbox> </Grid> Marek Tabędzki 8/62

(Viebox skaluje całą zawartość: nie tylko rozmiar samego kształtu, ale i np. grubość krawędzi, a także kontrolki, które w nim umieścimy). Własność Viewbox.Stretch domyślnie ustawiona jest na Uniform, ale można też użyć Fill i UniformToFill, aby zmienić sposób skalowania zawartości, a także StretchDirection (poza Both mamy UpOnly, aby tylko powiększać i DownOnly aby tylko zmniejszać). Uwaga: element umieszczony w ViewBoxie musi mieć określony rozmiar, aby Viewbox wiedział jak go przeskalować (tzn. jaki jest jego rozmiar bazowy). Marek Tabędzki 9/62

Line Własności X1, Y1 oraz X2, Y2 określają współrzędne początkowego i końcowego punktu linii. <Grid Margin="5"> <Line Stroke="Blue" X1="0" Y1="0" X2="100" Y2="10"/> </Grid> Dla linii określamy tylko właność Stroke (Fill nie jest brany pod uwagę). Współrzędne są określane w odniesieniu do lewego, górnego narożnika kontenera (plus Margin), w którym umieszczono kształt. W przeciwieństwie do Rectangle i Ellipse, możemy rysować linie poza kontenerem (np. podając ujemne współrzędne). Nie możemy za to ustawić dla nich marginesu i alignmentu. Nadal możemy określić położenie punktu początkowego linii w Canvasie przy pomocy Canvas.Top, Canvas.Left a rozmiar przy pomocy Width i Height. Marek Tabędzki 10/62

Polyline Pozwala narysować linię łamaną. Definiujemy ją przy pomocy listy współrzędnych X i Y. Można podać ją jako kolekcję punktów: <Polyline Stroke="MediumBlue" StrokeThickness="5"> <Polyline.Points> <PointCollection> <Point X="10" Y="110"/> <Point X="30" Y="120"/> <Point X="50" Y="100"/> <Point X="70" Y="140"/> <Point X="90" Y="80"/> <Point X="110" Y="170"/> <Point X="130" Y="50"/> <Point X="150" Y="170"/> <Point X="170" Y="80"/> <Point X="190" Y="140"/> </PointCollection> </Polyline.Points> </Polyline> Marek Tabędzki 11/62

Albo w skróconej formie, jako wartości oddzielane spacjami (przecinek między X a Y jest opcjonalny). <Polyline Stroke="MediumBlue" StrokeThickness="5" Points="10,90 30,100 50,80 70,120 90,60 110,150 130,30 150,150 170,60 190,120"/> Marek Tabędzki 12/62

Polygon Działa niemal tak samo jak Polyline. Jedyna różnica: Polygon jest krzywą zamkniętą (sam dodaje ostatni segment, łączący punkt końcowy z początkowym). Może używać pędzla wypełnienia (Fill). <Polygon Stroke="MediumBlue" Fill="LightBlue" StrokeThickness="5" Points="20,85 30,100 50,80 70,120 90,60 110,150 130,30 150,150 170,60 180,130"/> Marek Tabędzki 13/62

Są dwa sposoby wypełniania Polygonu. Domyślny: <Polygon Stroke="MediumBlue" Fill="LightBlue" FillRule="EvenOdd" StrokeThickness="5" Points="95,20 160,150 20,70 180,60 50,160"/> Marek Tabędzki 14/62

<Polygon Stroke="MediumBlue" Fill="LightBlue" FillRule="Nonzero" StrokeThickness="5" Points="95,20 160,150 20,70 180,60 50,160"/> Marek Tabędzki 15/62

Line Caps, Line Joins W wypadku rysowania linii możemy określić kształt zakończeń StrokeStartLineCap i StrokeEndLineCap: Flat (domyślne), Round, Square i Triangle (wszystkie zwiększają długość linii o ½ szerokości). <Canvas> <Polyline StrokeEndLineCap="Flat" Stroke="MediumBlue" StrokeThickness="20" Points="20,40 40,60 80,20 100,40 200,40"/> <Polyline StrokeEndLineCap="Round".../> <Polyline StrokeEndLineCap="Square".../> <Polyline StrokeEndLineCap="Triangle".../> </Canvas> Marek Tabędzki 16/62

StrokeLineJoin pozwala określić kształt łączeń (wierzchołków łamanej) Miter (domyślny), Bevel (ścięte narożniki), Round (zaokrąglone). Miter pozwala podać StrokeMiterLimit, który ogranicza wydłużanie narożników (wartość 1 to maksymalnie ½ szerokości linii). <Canvas> <Polyline Stroke="MediumBlue" StrokeThickness="20" StrokeLineJoin="Miter" Points="20,20 140,40 40,60 60,80"/> <Polyline StrokeLineJoin="Bevel".../> <Polyline StrokeLineJoin="Round".../> <Polyline StrokeLineJoin="Miter" StrokeMiterLimit="3".../> </Canvas> Marek Tabędzki 17/62

Dashes <Canvas> <Polyline StrokeDashArray="1".../> <Polyline StrokeDashArray="1 2".../> <Polyline StrokeDashArray="2 1".../> <Polyline StrokeDashArray="3 2 1 2".../> <Polyline StrokeDashArray="5 2 1".../> <Polyline StrokeDashArray="2 2" StrokeDashCap="Round".../> </Canvas> StrokeDashArray pozwala zdefiniować dowolny wzór linii przerywanej podajemy wartości, określające długość segmentu i przerwy między segmentami. Liczba tych wartości nie musi być parzysta. StrokeDashCap pozwala określić kształt zakończeń segmentów (uwaga na długość zwiększoną o ½ szerokości). StrokeDashOffset pozwala zacząć przerywaną od wybranej wartości wzorca. Marek Tabędzki 18/62

Pixel Snapping Uwaga: wymiary podajemy zawsze w jednostkach logicznych (1/96 cala). Mogą być to liczby całkowite. W zależności od urządzenia nie muszą się one tłumaczyć na faktyczne położenie pixeli. Domyślnie jest to niwelowane przez antyaliasing. Gdy nie jest to pożądane, można włączyć opcję SnapsToDevicePixels (można to ustawić osobno dla każdego kształtu) powoduje ona zaokrąglenie wartości do faktycznych pikseli urządzenia. Brushes Pędzle używane są zarówno do rysowania tła (background), pierwszego planu (foreground), krawędzi (border) elementów, jak też wypełnienia (fill) oraz obwiedni (stroke) kształtów. Pędzle obsługują powiadamianie o zmianie (gdy zmodyfikujemy pędzel, wszystkie elementy, które go używają, powinny się odrysować). Obsługują półprzeźroczystość (własność Opacity). Klasa SystemBrushes udostępnia pędzle używające kolorów systemowych (zdefiniowanych w ustawieniach użytkownika). Marek Tabędzki 19/62

Dostępne rodzaje pędzli: SolidColorBrush najprostszym rodzaj pędzla: wypełnia zawartość jednolitym kolorem. Jest on stosowany domyślnie, gdy podajemy sam kolor jako wartość własności w XAMLu. LinearGradientBrush, RadialGradientBrush wypełnienie gradientowe. ImageBrush wypełnienie przy pomocy obrazka. DrawingBrush wypełnienie przy użyciu własnej grafiki (np. kształtów). VisualBrush wypełnianie przy użyciu dowolnego obiektu typu Visual (a więc np. również elementów interfejsu przydatne do różnych efektów specjalnych). LinearGradientBrush Wymaga podania listy elementów GradientStop (każdy element to kolejny kolor). <Rectangle> <Rectangle.Fill> <LinearGradientBrush> <GradientStop Color="LightBlue" Offset="0" /> <GradientStop Color="MediumBlue" Offset="1" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> Marek Tabędzki 20/62

Offset określa położenie każdego koloru, można w ten sposób sterować szerokością przejścia: <Rectangle Margin="3"> <Rectangle.Fill> <LinearGradientBrush> <GradientStop Color="LightBlue" Offset="0.3" /> <GradientStop Color="MediumBlue" Offset="0.7" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> StartPoint i EndPoint pozwalają sterować kierunkiem gradientu. <Rectangle Margin="3"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Color="LightBlue" Offset="0" /> <GradientStop Color="MediumBlue" Offset="1" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> Marek Tabędzki 21/62

<Rectangle Margin="3"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="LightBlue" Offset="0" /> <GradientStop Color="MediumBlue" Offset="1" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle Margin="3"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,0.2" SpreadMethod="Reflect"> <GradientStop Color="LightBlue" Offset="0" /> <GradientStop Color="MediumBlue" Offset="1" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> Marek Tabędzki 22/62

<Rectangle Margin="3"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,0.2" SpreadMethod="Repeat"> <GradientStop Color="LightBlue" Offset="0" /> <GradientStop Color="MediumBlue" Offset="1" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> Można określić więcej kolorów składowych: <Rectangle Margin="3"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,1" EndPoint="0,0"> <GradientStop Color="Red" Offset="0" /> <GradientStop Color="White" Offset="0.5" /> <GradientStop Color="Black" Offset="1" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> (Uwaga: oczywiście, takiego pędzla możemy używać nie tylko do rysowania kształtów, ale i np. tekstu, krawędzi, etc.) Marek Tabędzki 23/62

RadialGradientBrush Kolory definiuje się, jak w LinearGradientBrush. Różnica polega na określeniu pozycji. <Ellipse Margin="3"> <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="1" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> <Ellipse Margin="3"> <Ellipse.Fill> <RadialGradientBrush Center="0.2,0.8"> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="1" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> Marek Tabędzki 24/62

<Ellipse Margin="3"> <Ellipse.Fill> <RadialGradientBrush GradientOrigin="0.2,0.8"> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="1" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> <Ellipse Margin="3"> <Ellipse.Fill> <RadialGradientBrush RadiusX="0.25" RadiusY="1"> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="1" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> Marek Tabędzki 25/62

ImageBrush <Rectangle Margin="3"> <Rectangle.Fill> <ImageBrush ImageSource="happy_face.png"> </ImageBrush> </Rectangle.Fill> </Rectangle> Viewbox pozwala wskazać fragment obrazka do użycia w roli pędzla (koordynaty względne). <Rectangle Margin="3"> <Rectangle.Fill> <ImageBrush ImageSource="happy_face.png" Viewbox="0.5 0.1 0.4 0.4"> </ImageBrush> </Rectangle.Fill> </Rectangle> Marek Tabędzki 26/62

Tiled ImageBrush Viewport określa względny rozmiar pojedynczego obrazka (a tym samym ile powtórzeń znajdzie się w wypełnianym obszarze niezależnie od jego rozmiaru). <Ellipse Margin="3" Stroke="Black"> <Ellipse.Fill> <ImageBrush ImageSource="happy_face.png" TileMode="Tile" Viewport="0,0 0.4,0.5"> </ImageBrush> </Ellipse.Fill> </Ellipse> <Ellipse Margin="3" Stroke="Black"> <Ellipse.Fill> <ImageBrush ImageSource="happy_face.png" TileMode="FlipXY" Viewport="0,0 0.4,0.5"> </ImageBrush> </Ellipse.Fill> </Ellipse> Marek Tabędzki 27/62

Ustawienie ViewportUnits jako Absolute spowoduje, że obrazek nie będzie skalowany, a powtarzany ilość razy zależną od rozmiaru figury. <Ellipse Margin="3" Stroke="Black"> <Ellipse.Fill> <ImageBrush ImageSource="happy_face.png" ViewportUnits="Absolute" TileMode="Tile" Viewport="0,0 48,48"> </ImageBrush> </Ellipse.Fill> </Ellipse> Marek Tabędzki 28/62

VisualBrush Pozwala pobrać obraz dowolnego elementu i używać go jako pędzla. Uwaga: kopiuje to tylko wygląd elementu, skopiowane kontrolki nie dadzą się używać. Pędzel reaguje na zmianę wyglądu kontrolki (np. naciśnięcie przycisku, wpisanie wartości do pola tekstowego). <StackPanel> <Button Margin="3" Name="ok">OK</Button> <Rectangle Margin="3" Height="{Binding ElementName=ok, Path=ActualHeight}"> <Rectangle.Fill> <VisualBrush Visual="{Binding ElementName=ok}"/> </Rectangle.Fill> </Rectangle> <Rectangle Margin="3" Height="50"> <Rectangle.Fill> <VisualBrush Visual="{Binding ElementName=ok}"/> </Rectangle.Fill> </Rectangle> </StackPanel> Jest to używane np. aby pokazać podgląd zawartości okna, wygenerować miniaturę, albo do efektów specjalnych (odbicia, cienie, animacje). Marek Tabędzki 29/62

Transforms Transformacje afiniczne. Wszystkie klasy dziedziczą z System.Windows.Media.Transform. TranslateTransform translacja (własności X i Y) RotateTransform obrót (Angle, CenterX, CenterY) ScaleTransform skalowanie (ScaleX, ScaleY, CenterX, CenterY) SkewTransform pochylenie (AngleX, AngleY, CenterX, CenterX) MatrixTransform dowolne przekształcenie z wykorzystaniem własnej macierzy przekształcenia (Matrix) TransformGroup łączy kilka transformacji (ich kolejność jest ważna) Aby transformować kształt należy ustawić własność RenderTransform. W obrocie określamy kąt: <Canvas Margin="3"> <Rectangle Stroke="DarkBlue" Width="150" Height="20"> <Rectangle.RenderTransform> <RotateTransform Angle="10"/> </Rectangle.RenderTransform> </Rectangle>... </Canvas> Marek Tabędzki 30/62

Można też wybrać środek obrotu: <Canvas Margin="3"> <Rectangle Stroke="DarkBlue" Width="150" Height="20"> <Rectangle.RenderTransform> <RotateTransform Angle="10" CenterX="75" CenterY="10"/> </Rectangle.RenderTransform> </Rectangle>... </Canvas> Środek można też wskazać jako wartość względną: <Canvas Margin="3"> <Rectangle Stroke="DarkBlue" Width="150" Height="20" RenderTransformOrigin="0.2,0.5"> <Rectangle.RenderTransform> <RotateTransform Angle="10" /> </Rectangle.RenderTransform> </Rectangle>... </Canvas> Marek Tabędzki 31/62

Transforming Elements Te same transformacje mogą być stosowane również w stosunku do elementów: <Button Margin="3" Name="ok" RenderTransformOrigin="0.5,0.5"> <Button.RenderTransform> <TransformGroup> <SkewTransform AngleX="-45" /> <RotateTransform Angle="30"/> <TranslateTransform Y="50"/> </TransformGroup> </Button.RenderTransform> OK</Button> Dostępne jest jeszcze LayoutTransform, które jest aplikowane przed ułożeniem zawartości. <StackPanel> <Button Margin="3" Name="ok" RenderTransformOrigin="0.5,0.5"> <Button.LayoutTransform> <TransformGroup> <RotateTransform Angle="45"/> </TransformGroup> </Button.LayoutTransform> OK</Button> </StackPanel> Marek Tabędzki 32/62

Transparency Sposoby na efekt przeźroczystości: Własność Opacity elementu (od 1 nieprzejrzysty do 0 całkowicie przeźroczysty). Opacity pędzla wówczas dotyczy tylko tego, co jest rysowane tym pędzlem. Użycie koloru o wartości alfa mniejszej niż 255 (często daje lepsze efekty niż ustawienie Opacity). <StackPanel Background="LawnGreen"> <Button Margin="3"> Nieprzejrzysty </Button> <Button Margin="3" Opacity="0.5" Background="Yellow"> Półprzeźroczysty </Button> <Button Margin="3" Background="#80FFFF00"> Półprzeźroczysty kolor </Button> </StackPanel> Marek Tabędzki 33/62

Opacity Masks W odróżnieniu od Opacity, która ustawia jeden poziom przeźroczystości dla całego elementu, Opacity Mask pozwala na bardziej urozmaicone efekty. Akceptuje dowolny pędzel i używa jego kanału alfa (kolor nie jest ważny) by określić przezroczystość. <StackPanel Background="LawnGreen"> <Button Margin="3" Padding="3"> <Button.OpacityMask> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="#00000000" Offset="0"/> <GradientStop Color="#ff000000" Offset="1"/> </LinearGradientBrush> </Button.OpacityMask> Opacity Mask </Button> </StackPanel> Marek Tabędzki 34/62

Wykorzystanie do efektu lustra: <StackPanel> <Button Margin="3" Name="ok">Naciśnij mnie</button> <Rectangle Margin="3" Height="{Binding ElementName=ok, Path=ActualHeight}" RenderTransformOrigin="0,0.5"> <Rectangle.Fill> <VisualBrush Visual="{Binding ElementName=ok}"/> </Rectangle.Fill> <Rectangle.RenderTransform> <ScaleTransform ScaleY="-1"/> </Rectangle.RenderTransform> <Rectangle.OpacityMask> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Transparent" Offset="0.3"/> <GradientStop Color="#80000000" Offset="1"/> </LinearGradientBrush> </Rectangle.OpacityMask> </Rectangle> </StackPanel> Marek Tabędzki 35/62

Ścieżki i geometrie Path to najbardziej złożony z dostępnych kształtów (shapes). Może zastąpić dowolne z innych kształtów, a także umożliwia łączenie kształtów oraz posługiwanie się krzywymi. Klasa Path ma własność Data, pobierającą obiekt typu Geometry. Definiuje on kształt (lub kształty) wchodzące w skład ścieżki. Proste geometrie: LineGeometry linia prosta. RectangleGeometry odpowiednik kształtu Rectangle. EllipseGeometry elipsa. Geometrie złożone: GeometryGroup dodaje dowolną liczbę geometrii do jednej ścieżki. CombinedGeometry łączy dwie geometrie w jedne kształt. Pozwala wybrać sposób połączenia. PathGeometry reprezentuje złożoną figurę (otwartą lub zamkniętą), składającą się z sekwencji łuków, odcinków i krzywych. Marek Tabędzki 36/62

Ścieżka jako zamiennik kształtu: <Rectangle Fill="Yellow" Stroke="Blue" Width="100" Height="50" /> <Line Stroke="Blue" X1="0" Y1="0" X2="10" Y2="100"/> <Ellipse Fill="Yellow" Stroke="Blue" Width="100" Height="50" HorizontalAlignment="Left"/> <Path Fill="Yellow" Stroke="Blue"> <Path.Data> <RectangleGeometry Rect="0,0 100,50"/> </Path.Data> </Path> <Path Fill="Yellow" Stroke="Blue"> <Path.Data> <LineGeometry StartPoint="0,0" EndPoint="10,100"/> </Path.Data> </Path> <Path Fill="Yellow" Stroke="Blue"> <Path.Data> <EllipseGeometry RadiusX="50" RadiusY="25" Center="50,25"/> </Path.Data> </Path> W tej chwili jedyna widoczna korzyść to to, że nie musimy umieszczać ich w Canvas. Prawdziwe możliwości pojawiają się gdy zechcemy połączyć kilka geometrii. Marek Tabędzki 37/62

Łączenie kształtów przy pomocy GeometryGroup To najprostszy sposób połączenie geometrii: <Path Fill="Yellow" Stroke="Blue" Margin="5" Canvas.Top="10" Canvas.Left="10" > <Path.Data> <GeometryGroup> <RectangleGeometry Rect="0,0 100,100"/> <EllipseGeometry Center="150,50" RadiusX="35" RadiusY="25"/> </GeometryGroup> </Path.Data> </Path> Plusy: jeden obiekt zamiast dwóch większa wydajność (jeden element złożony działa szybciej niż wiele elementów prostych) grupy kształtów można definiować w zasobach i wykorzystywać w innych elementach ścieżkach Marek Tabędzki 38/62

Bardziej urozmaicone sposoby łączenia kształtów oferuje CombinedGeometry Może ona łączyć tylko dwie geometrie (własności Geometry1 i Geometry2). GeometryCombineMode określa wykonywaną na nich operację: Union suma Intersect część wspólna Xor alternatywa wykluczająca Exclude różnica <Path Fill="Yellow" Stroke="Blue" Canvas.Top="40" Canvas.Left="20"> <Path.Data> <CombinedGeometry GeometryCombineMode="Union"> <CombinedGeometry.Geometry1> <RectangleGeometry Rect="0,0 100,100"/> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <EllipseGeometry Center="80,10" RadiusX="35" RadiusY="35"/> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> </Path> Marek Tabędzki 39/62

GeometryCombineMode="Intersect" GeometryCombineMode="Xor" GeometryCombineMode="Exclude" Marek Tabędzki 40/62

Bardziej złożone kształty należy składać z kilku CombinedGeometry. <CombinedGeometry GeometryCombineMode="Union"> <CombinedGeometry.Geometry1> <CombinedGeometry GeometryCombineMode="Exclude"> <CombinedGeometry.Geometry1> <EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50"/> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <EllipseGeometry Center="50,50" RadiusX="40" RadiusY="40"/> </CombinedGeometry.Geometry2> </CombinedGeometry> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <RectangleGeometry Rect="0,45,100,10"> <RectangleGeometry.Transform> <RotateTransform Angle="-45" CenterX="50" CenterY="50"/> </RectangleGeometry.Transform> </RectangleGeometry> </CombinedGeometry.Geometry2> </CombinedGeometry> Marek Tabędzki 41/62

Efekt: Marek Tabędzki 42/62

Geometry Mini-Language Pozwala zdefiniować geometrię w formie tekstu zawierającego ciąg poleceń. Każde polecenie to litera i wartości liczbowe oddzielane spacjami. Ścieżka jest wówczas zbiorem połączonych linii i krzywych mogących tworzyć zamknięte lub otwarte obszary. Przykład: <Path Stroke="Blue" StrokeThickness="5" Data="M 20,20 L 90,50 L 50,90 Z"/> Przecinki są opcjonalne, ale poprawiają czytelność. Marek Tabędzki 43/62

Dostępne polecenia: F value ustawia własność Geometry.FillRule (0 oznacza EvenOdd, 1 Nonzero). Może pojawić się tylko na początku stringu. M x,y tworzy nową ścieżkę i ustawia punkt startowy. Musi pojawić się przed jakąkolwiek inną (poza F), ale może pojawić się też później, by przemieścić punkt startowy (M znaczy Move). L x,y tworzy odcinek (linię) do wskazanego punktu H x tworzy poziomy odcinek V y tworzy pionowy odcinek A radiusx, radiusy degrees islargearc, isclockwise x,y tworzy łuk elipsy do wskazanego punktu, podajemy promienie elipsy i wybieramy która część nas interesuje C x1,y1 x2,y2 x,y tworzy krzywą Beziera z punktami kontrolnymi x1,y1 i x2,y2 Q x1, y1 x,y prostsza forma krzywej Beziera (Quadratic Bezier), z jednym punktem kontrolnym S x2,y2 x,y tworzy kolejny segment Beziera, wykorzystując ostatni punkt kontrolny z poprzedniej krzywej (Smooth Bezier) Z kończy PathFigure i ustawia powoduje jej zamknięcie (nie jest obowiązkowe, jeśli chcemy mieć figurę otwartą) Polecenie zapisane małymi znakami oznacza, że parametry są podane względem poprzedniego punktu (a nie wartości absolutne). Marek Tabędzki 44/62

Animacje Animacje w WPF definiuje się przeważnie w sposób deklaratywny (w XAML). Stworzenie animacji wymaga określenia jaka właściwość elementu w jaki sposób ma się zmieniać w czasie. Ograniczenie: animacje dotyczą tylko dependency properties (a co za tym idzie, nie da się uzyskać w ten sposób efektów, których nie osiągniemy modyfikując własności, np. nie można animacją dodawać elementów do okna). Mogą one służyć uatrakcyjnieniu standardowej aplikacji, ale nie nadają się np. do gier. Każda animacja operuje na pojedynczej własności. Animowanie własności wymaga użycia klasy animacji właściwej dla typu tej własności. Klasy animacji: zmieniających pewną wartość na drodze liniowej interpolacji (z wartości From do wartości To lub zwiększając wartość aktualną o By), np. DoubleAnimation zmieniających pewną wartość w określonych punktach czasu, np. DoubleAnimationUsingKeyFrames animacje wykorzystujące ścieżkę (PathGeometry), np. DoubleAnimationUsingPath Nie ma klas do animowania własności typu wyliczeniowego (np. HorizontalAlignment). Zazwyczaj nie animuje się też typów referencyjnych (np. Brush zamiast tego używa się np. ColorAnimation, DoubleAnimation do animacji własności pędzla). Marek Tabędzki 45/62

Przykład: Animacja w XAMLu definiowana jest w obiekcie storyboard. Reprezentuje on przebieg animacji, pozwala na grupowanie kilku animacji, kontrolowanie animacji. Do uruchomienia animacji konieczny jest EventTrigger. Jego zadaniem jest odpalenie animacji. <Window.Triggers> <EventTrigger RoutedEvent="Window.Loaded"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation From="0" To="300" Duration="0:0:1" Storyboard.TargetName="pr" Storyboard.TargetProperty="(Canvas.Left)"/> <DoubleAnimation From="0" To="200" Duration="0:0:1" Storyboard.TargetName="pr" Storyboard.TargetProperty="(Canvas.Top)"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Window.Triggers> Marek Tabędzki 46/62

<Canvas> <Rectangle Name="pr" Width="20" Height="20" Fill="Orange" Stroke="Black" StrokeThickness="2"/> </Canvas> Marek Tabędzki 47/62

Inne właściwości animacji: <Storyboard> <DoubleAnimation From="0" To="300" BeginTime="0:0:2" AutoReverse="True" RepeatBehavior="Forever" AccelerationRatio="0.2" DecelerationRatio="0.2" Duration="0:0:1" Storyboard.TargetName="pr" Storyboard.TargetProperty="(Canvas.Left)"/> <DoubleAnimation From="0" To="200" BeginTime="0:0:2" AutoReverse="True" RepeatBehavior="Forever" AccelerationRatio="0.2" DecelerationRatio="0.2" Duration="0:0:1" Storyboard.TargetName="pr" Storyboard.TargetProperty="(Canvas.Top)"/> </Storyboard> Marek Tabędzki 48/62

Posługiwanie się animacjami Co animować? Jeśli chcemy, by elementy pojawiały się i znikały: Opacity. Jeśli chcemy przemieszczać elementy: Canvas.Left, Canvas.Top (jeśli kontenerem jest Canvas), ewentualnie Margin lub/i Padding (przy pomocy ThicknessAnimation), ewentualnie MinWidth i MinHeight kolumny lub wiersza w Gridzie. RenderTransform aby przemieszczać (TranslateTransform), obracać (RotateTransform), skalować (ScaleTransform) elementy. Działają szybciej niż animacja własności określających rozmiar czy pozycję. ColorAnimation aby modyfikować własności pędzla. Marek Tabędzki 49/62

Animacja transformacji Każdy element ma dwa rodzaje transformacji: RenderTransform (stosowana przed wyświetleniem obiektu) i LayoutTransform (stosowana przed ułożeniem elementów przez kontener). (Animacja nie może stworzyć transformacji, a jedynie animować własności istniejącej.) Przykład: obracający się przycisk. <Button RenderTransformOrigin="0.5,0.5"> <Button.RenderTransform> <RotateTransform/> </Button.RenderTransform> OK </Button> Marek Tabędzki 50/62

EventTrigger do uruchomienia animacji: <EventTrigger RoutedEvent="Button.MouseEnter"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty= "RenderTransform.Angle" To="360" Duration= "0:0:1" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> Marek Tabędzki 51/62

I do zakończenia (powrotu do stanu początkowego nie określamy wartości docelowej): <EventTrigger RoutedEvent="Button.MouseLeave"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty= "RenderTransform.Angle" Duration="0:0:0.2"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> Marek Tabędzki 52/62

Parametry przycisku możemy ustawić w stylu: <Style TargetType="Button"> <Setter Property="Margin" Value="3" /> <Setter Property="Padding" Value="20,3"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/> <Setter Property="RenderTransform"> <Setter.Value> <RotateTransform></RotateTransform> </Setter.Value> </Setter> <Style.Triggers> <EventTrigger... <EventTrigger... </Style.Triggers> </Style> Marek Tabędzki 53/62

Teraz każdy z przycisków będzie używał tej animacji: <StackPanel> <Button>jeden</Button> <Button>dwa</Button> <Button>trzy</Button> <Button>cztery</Button> <Button>pięć</Button> </StackPanel> Marek Tabędzki 54/62

Jeśli wymienimy RenderTransform na LayoutTransform: Marek Tabędzki 55/62

Animowanie pędzli Kolor pędzla animujemy przy pomocy klasy ColorAnimation. Wymaga stworzenia pędzla: <Ellipse Stretch="Uniform" Margin="3" Name="elipsa"> <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color="Yellow" Offset="0"/> <GradientStop Color="LawnGreen" Offset="1"/> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> Marek Tabędzki 56/62

Teraz możemy ustawić jego właściwości: <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetName="elipsa" To="DeepSkyBlue" Storyboard.TargetProperty= "Fill.GradientStops[1].Color" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> Marek Tabędzki 57/62

PointAnimation pozwala przemieszczać punkt (działa to jak DoubleAnimation składowej X i Y). Dzięki temu możemy np. modyfikować kształt figury zbudowanej z punktów. W poniższym przykładzie animujemy centralny punkt gradientu radialnego. <PointAnimation Storyboard.TargetName="elipsa" Storyboard.TargetProperty="Fill.GradientOrigin" From="0.7,0.3" To="0.3,0.7" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever" /> Marek Tabędzki 58/62