📌 Что такое WPF графика?
WPF — это система для создания оконных приложений. Графика в WPF работает через векторную модель: фигуры, пути, преобразования.
- Canvas — контейнер для рисования (координаты x, y).
- Shapes — Rectangle, Ellipse, Line, Path.
- Transform — поворот, масштаб, сдвиг.
- Clip — обрезка по форме.
- Storyboard — анимация свойств.
💡 Важно: WPF использует аппаратное ускорение (DirectX), поэтому графика работает быстро.
📦 Canvas — холст для рисования
Canvas — это панель, на которой можно размещать элементы в абсолютных координатах через Canvas.Left и Canvas.Top.
<Canvas Width="400" Height="300" Background="#f0f4fa">
<Rectangle Width="100" Height="80" Fill="#4a8fe0" Canvas.Left="20" Canvas.Top="30" />
<Ellipse Width="80" Height="80" Fill="#e06a4a" Canvas.Left="160" Canvas.Top="40" />
</Canvas>
☝️ Координаты считаются от левого верхнего угла Canvas.
▬ Rectangle — прямоугольник
Задаётся шириной, высотой, цветом заливки (Fill) и границей (Stroke).
<Rectangle Width="150" Height="80" Fill="cornflowerblue" Stroke="#1a3b5c" StrokeThickness="4" RadiusX="10" RadiusY="10" />
🎯 RadiusX и RadiusY делают углы скруглёнными.
⚪ Ellipse — круг и овал
Рисует эллипс. Если Width == Height — получается круг.
<Ellipse Width="100" Height="100" Fill="#ffb347" Stroke="#d48a00" StrokeThickness="3" />
🧠 Центр эллипса определяется автоматически, но можно сдвинуть через Canvas.Left/Top.
📏 Line — линия
Рисует отрезок от (X1,Y1) до (X2,Y2).
<Line X1="20" Y1="50" X2="300" Y2="150" Stroke="#e06a4a" StrokeThickness="4" />
✏️ Линия не имеет заливки (Fill), только Stroke.
✏️ Path — сложные фигуры
Path позволяет рисовать любые контуры через Data (синтаксис похож на SVG).
<Path Fill="gold" Data="M 50,0 L 65,30 L 100,30 L 70,50 L 80,90 L 50,65 L 20,90 L 30,50 L 0,30 L 35,30 Z" />
📖 M = move, L = line, Z = закрыть фигуру.
🔤 Команды Path (коротко)
M x,y — переместить в точку
L x,y — провести линию
Z — закрыть контур
A rx,ry x-axis-rotation large-arc sweep x,y — дуга
C x1,y1 x2,y2 x,y — кривая Безье
💡 На практике для 2 курса достаточно M, L, Z.
🎨 Цвета и кисти (Brushes)
- SolidColorBrush — сплошной цвет (
Fill="Red").
- LinearGradientBrush — градиент по прямой.
- RadialGradientBrush — радиальный градиент.
<Rectangle Width="200" Height="100">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="Blue" Offset="0.5"/>
<GradientStop Color="Green" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
🔄 RotateTransform — поворот
Поворачивает фигуру на заданный угол (в градусах).
<Rectangle Width="100" Height="50" Fill="#4a8fe0">
<Rectangle.RenderTransform>
<RotateTransform Angle="45" CenterX="50" CenterY="25" />
</Rectangle.RenderTransform>
</Rectangle>
🧭 CenterX, CenterY — точка вращения (относительно фигуры).
📐 ScaleTransform — масштабирование
Увеличивает или уменьшает фигуру.
<Rectangle Width="100" Height="60" Fill="#e06a4a">
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="1.5" ScaleY="1.5" />
</Rectangle.RenderTransform>
</Rectangle>
📏 ScaleX=2 — ширина в 2 раза, ScaleY=0.5 — высота в половину.
➡️ TranslateTransform — сдвиг
Перемещает фигуру на заданное смещение.
<Rectangle Width="80" Height="40" Fill="#4a8fe0">
<Rectangle.RenderTransform>
<TranslateTransform X="50" Y="30" />
</Rectangle.RenderTransform>
</Rectangle>
🔄 TranslateTransform работает как Canvas.Left/Top, но в составе преобразования.
✂️ Clip — обрезка по форме
Обрезает содержимое элемента по заданной геометрии.
<Rectangle Width="300" Height="200" Fill="#4a8fe0">
<Rectangle.Clip>
<EllipseGeometry Center="150,100" RadiusX="100" RadiusY="60" />
</Rectangle.Clip>
</Rectangle>
✂️ Видна только та часть, которая попадает внутрь Clip.
🎬 Storyboard — анимация
Storyboard управляет анимацией. DoubleAnimation меняет числовые свойства (например, Canvas.Left).
<Window.Resources>
<Storyboard x:Key="MoveBall">
<DoubleAnimation Storyboard.TargetName="Ball" Storyboard.TargetProperty="(Canvas.Left)"
From="10" To="350" Duration="0:0:2" AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</Window.Resources>
▶️ Запуск: ((Storyboard)FindResource("MoveBall")).Begin();
⚙️ Параметры DoubleAnimation
From — начальное значение
To — конечное значение
Duration — длительность (например, "0:0:2" = 2 секунды)
AutoReverse — вернуться обратно
RepeatBehavior — сколько раз повторять (Forever, 3x)
💡 AutoReverse="True" часто используют, чтобы фигура ходила туда-сюда.
🎯 Анимация нескольких свойств
Можно добавить несколько DoubleAnimation в один Storyboard.
<Storyboard x:Key="StarAnimation">
<DoubleAnimation Storyboard.TargetName="Star" Storyboard.TargetProperty="(Canvas.Left)"
From="50" To="550" Duration="0:0:3" AutoReverse="True" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetName="Star" Storyboard.TargetProperty="(Canvas.Top)"
From="50" To="350" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
⭐ Звезда будет двигаться по диагонали туда-сюда.
⭐ Пример: летающая звезда (XAML)
<Window x:Class="StarGame.MainWindow" ...>
<Canvas x:Name="GameCanvas" Background="#f5f7fa" ClipToBounds="True">
<Path x:Name="Star" Fill="gold" Stroke="#d48a00" StrokeThickness="2"
Data="M 50,0 L 65,30 L 100,30 L 70,50 L 80,90 L 50,65 L 20,90 L 30,50 L 0,30 L 35,30 Z" />
</Canvas>
<Button Content="Старт" Click="StartAnimation" />
</Window>
🎯 Добавьте Storyboard в Window.Resources и запустите в C#.
💻 Пример: летающая звезда (C#)
private void StartAnimation(object sender, RoutedEventArgs e)
{
Storyboard sb = (Storyboard)FindResource("StarAnimation");
sb.Begin();
}
📌 FindResource ищет ресурс по имени. Begin() запускает анимацию.
🌀 Анимация вращения (RotateTransform)
<Path x:Name="Star" Fill="gold" Stroke="#d48a00" StrokeThickness="2"
Data="M 50,0 L 65,30 L 100,30 L 70,50 L 80,90 L 50,65 L 20,90 L 30,50 L 0,30 L 35,30 Z">
<Path.RenderTransform>
<RotateTransform x:Name="StarRotation" Angle="0" CenterX="50" CenterY="45" />
</Path.RenderTransform>
</Path>
<!-- Анимация в C# -->
DoubleAnimation rotateAnim = new DoubleAnimation();
rotateAnim.From = 0;
rotateAnim.To = 360;
rotateAnim.Duration = TimeSpan.FromSeconds(3);
rotateAnim.RepeatBehavior = RepeatBehavior.Forever;
StarRotation.BeginAnimation(RotateTransform.AngleProperty, rotateAnim);
⏲️ DispatcherTimer — ручное движение
Если нужно сложное управление (например, игра), используют DispatcherTimer.
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(30);
timer.Tick += (s, e) => {
Canvas.SetLeft(ball, Canvas.GetLeft(ball) + 3);
if (Canvas.GetLeft(ball) > 500) Canvas.SetLeft(ball, 0);
};
timer.Start();
⏳ Timer срабатывает каждые 30 мс — плавное движение.
❄️ Пример: падающий снег (частицы)
// Создаём снежинки в таймере
private void SpawnSnow()
{
Ellipse snow = new Ellipse();
snow.Width = 10; snow.Height = 10;
snow.Fill = Brushes.White;
Canvas.SetLeft(snow, rnd.Next(0, 600));
Canvas.SetTop(snow, -10);
GameCanvas.Children.Add(snow);
// В таймере: двигаем каждую снежинку вниз
}
🌨️ Идея: создавать снежинки каждые 200 мс, двигать вниз, удалять при выходе за экран.
🎯 Итоговое задание на две пары
Создать игру или симулятор с графикой WPF
- Использовать Canvas и минимум 3 вида фигур.
- Добавить анимацию (Storyboard или Timer).
- Использовать Transform (поворот или масштаб).
- Применить Clip для обрезки.
- Добавить реакцию на мышь или клавиши.
💡 Идеи: «Щелкни по звезде», «Падающий снег», «Космический защитник».
📤 Как сдать работу
- Папка проекта (целиком) — на следующем занятии.
- В коде должны быть комментарии (что делает каждая часть).
- Один скриншот работы программы.
- Код должен запускаться без ошибок.
✅ Каждый пункт из списка выше — +1 балл к оценке.
📋 Шпаргалка — XAML
Фигуры
Rectangle — прямоугольник
Ellipse — круг/овал
Line — линия
Path — сложная фигура
Преобразования
RotateTransform — поворот
ScaleTransform — масштаб
TranslateTransform — сдвиг
📋 Шпаргалка — C#
FindResource("имя") — найти ресурс
Begin() — запустить анимацию
Canvas.SetLeft(element, value) — задать X
Canvas.GetLeft(element) — получить X
DispatcherTimer — таймер для движения
💡 Эти методы понадобятся для игры.
❓ Вопросы и обсуждение
- Какая разница между
Canvas и Grid?
- Что будет, если не задать
CenterX в RotateTransform?
- Как сделать, чтобы анимация повторялась бесконечно?
- Зачем нужен
Clip?
💬 Задавайте вопросы — я помогу разобраться.
📚 Полезные ссылки
- Официальная документация Microsoft: WPF Graphics
- gadget59.ru — примеры и компоненты
- WPF Path Geometry — шпаргалка по командам
- Примеры анимаций на GitHub
🔗 На сайте gadget59.ru есть много готовых примеров.
✅ Итоги
- WPF графика — векторная, работает через
Canvas и фигуры.
Path позволяет рисовать сложные формы.
- Преобразования (
Transform) поворачивают, масштабируют, сдвигают.
Clip обрезает по геометрии.
- Анимация через
Storyboard и DoubleAnimation.
- Итоговое задание — игра или симулятор.
🌟 Удачи с проектом! Если что-то непонятно — спрашивайте.
🎮 Бонус: пример игры «Щелкни по звезде»
// Полный код игры (упрощённо)
public partial class MainWindow : Window
{
private int score = 0;
private Storyboard anim;
public MainWindow()
{
InitializeComponent();
anim = (Storyboard)FindResource("StarAnimation");
anim.Begin();
}
private void Star_Click(object sender, RoutedEventArgs e)
{
score++;
ScoreLabel.Content = "Счёт: " + score;
}
}
⭐ Это основа. Добавьте перезапуск, паузу, вторую звезду — задание готово.
❄️ Бонус: пример снега (частицы)
DispatcherTimer snowTimer = new DispatcherTimer();
snowTimer.Interval = TimeSpan.FromMilliseconds(200);
snowTimer.Tick += (s, e) => {
Ellipse flake = new Ellipse();
flake.Width = flake.Height = rnd.Next(5, 15);
flake.Fill = Brushes.White;
Canvas.SetLeft(flake, rnd.Next(0, 600));
Canvas.SetTop(flake, -10);
GameCanvas.Children.Add(flake);
// В отдельном таймере двигаем все снежинки вниз
};
snowTimer.Start();
🌨️ Снежинки падают сверху вниз, создавая эффект снегопада.
🙏 Спасибо за внимание!
Вопросы? — Пишите в чат или задавайте в аудитории.
WPF
Graphics
Canvas
Animation
📌 Не забудьте сдать итоговое задание на следующем занятии.