Анимацию в XAML можно разделить на две категории – линейную, при которой свойство плавно меняется с течением времени и покадровую, напоминающую классическую мультипликацию. Элементы и атрибуты, описывающие код, практически одинаковы в обеих категориях. Рассмотрим сначала линейную анимацию.
Фрагмент кода, описывающий движение прямоугольника, выглядит так:
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)"
From="0" To="200"
Duration="0:0:01"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Анимация происходит в ответ на события. Эта концепция очень похожа на общую модель событий объектно-ориентированного программирования вообще и, например, языка C# в частности. События определяются при помощи триггеров здесь – в данном примере эту роль играет элемент Rectangle Triggers. Значение "Rectangle.Loaded" атрибута RoutedEvent элемента EventTrigger указывает на то, что анимация начнется сразу после загрузки прямоугольника. Далее при помощи тега BeginStoryboard (начать раскадровку) определяется раскадровка Storyboard. Именно в элементе Storyboard определяются свойства, которые и будут меняться с течением времени. Элемент DoubleAnimation указывает на то, что анимируемое свойство является числом (типа Double ). Это один из трех возможных типов, другие приводятся в табл. 7.1.
| Элемент | Описание |
|---|---|
DoubleAnimation |
Задание анимации свойства в виде числа (поддерживаются дробные значения). |
ColorAnimation |
Анимация изменения цвета |
PointAnimation |
Изменение координат точки, задаваемой с помощью элемента Path |
Описание анимируемого объекта задается с помощью атрибутов, перечень которых приводится в табл. 7.2.
| Элемент | Описание |
|---|---|
Storyboard.TargetName |
Название объекта, свойство которого будет анимироваться. Это название предварительно задается в описании самого объекта при помощи атрибута x:Name |
Storyboard.TargetProperty |
Название свойства (атрибута), которое будет изменяться |
From |
Начальное значение анимируемого свойства. Если в описании объекта уже указано нужное значение From, то в описании анимации этот атрибут можно опустить |
To |
Конечное значение анимируемого свойства |
Duration |
Продолжительность изменения анимируемого свойства в формате "часы : минуты : секунды". Это не общая продолжительность анимации. Например, если задать перемещение объекта из точки 0,0 в точку 200,200 и указать значение Duration ="0:0:01", то этот объект и будет двигаться в течении одной секунды. Однако сколько раз он так будет перемещаться, определяет атрибут RepeatBehavior |
RepeatBehavior |
Поведение объекта после завершения анимации или общая продолжительность анимации. Возможны следующие значение: |
AutoReverse |
Автоматическое обращения воспроизведения, возможные значения "True" и "False" (по умолчанию). Например, если задать перемещение объекта из точки 0,0 в точку 200,200 и задать AutoReverse=" True ", то при достижении точки 200, 200 объект будет двигаться в обратном направлении |
By |
Относительное конечное значение анимируемого свойства. Например, если задать перемещение объекта из точки 100 в точку 300, то это можно сделать так:From="100" To="300" В этом случае происходит относительное смещение на 200 единиц. С помощью атрибута From="0" By="200" При одновременно задании обоих свойств To будет иметь больший приоритет, а |
BeginTime |
Задание времени старта анимации. Например, при значении BeginTime="0:0:3" анимация начнет воспроизводиться спустя три секунды |
SpeedRatio |
Коэффициент скорости. Предположим, что была установлено пятисекундное изменение некоторого свойства: Duration ="0:0:05". Это значение можно увеличить до 10 секунд, если указать SpeedRatio="0.5". Наоборот, при значении SpeedRatio="2" воспроизведение сократится до двух с половиной секунд |
Несмотря на большое количество атрибутов, отметим, что для создания анимации достаточно всего несколько ключевых значений.
Элемент DoubleAnimation позволяет анимировать числовые (включая дробные) значения свойств. Это означает, что с помощью этого элемента можно изменять наибольшее количество свойств объектов. В самом деле – координаты, размеры, прозрачность, направление градиента – все эти параметры задаются в виде чисел. В табл. 7.3 приводятся различные примеры с элементом DoubleAnimation.
| № | Код | Вид в браузере |
|---|---|---|
| 7.3.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="
Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle
.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="my
Rectangle"
Storyboard.TargetProperty="
(Canvas.Left)"
From="0" To="200"
Duration="0:0:01"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
Изменение абсциссы прямоугольника. Значение "Canvas.Left" атрибута Storyboard.TargetProperty было взято в скобки, поскольку оно состоит из двух слов. Анимация будет воспроизводиться бесконечно ( RepeatBehavior="Forever" ), а прямоугольник будет курсировать от одной точки к другой и обратно ( AutoReverse="True" ). |
||
| № | Код | Вид в браузере |
| 7.3.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="3x"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="
(Canvas.Left)"
From="0" To="200"
Duration="0:0:01"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
Трехкратное повторение анимации за счет свойства RepeatBehavior="3x". |
||
| № | Код | Вид в браузере |
| 7.3.3 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="90"
Canvas.Top="40" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="
(Canvas.Top)"
From="0" To="100"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Изменение ординаты прямоугольника | ||
| № | Код | Вид в браузере |
| 7.3.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="0"
Canvas.Top="40" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent=
"Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="
myRectangle"
Storyboard.TargetProperty="
(Canvas.Top)"
From="0" To="100"
Duration="0:0:05"
AutoReverse="True" />
<DoubleAnimation
RepeatBehavior="3x"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Canvas.Left)"
From="0" To="200"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Одновременное увеличение абсциссы и ординаты, в результате чего прямоугольник будет двигаться по диагонали | ||
| № | Код | Вид в браузере |
| 7.3.5 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
RepeatBehavior="Forever"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Width)"
From="0" To="195"
Duration="0:0:05"
AutoReverse="True" />
<DoubleAnimation RepeatBehavior=
"3x"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Height)"
From="0"
To="95"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Одновременное увеличение ширины и высоты прямоугольника | ||
| № | Код | Вид в браузере |
| 7.3.6 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="10"
Canvas.Top="10" Width="180"
Height="80" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Rectangle.Opacity)"
From="1" To="0"
Duration="0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Изменение прозрачности фигуры | ||
| № | Код | Вид в браузере |
| 7.3.7 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="150" Height="150"
Background="White"
x:Name="Page">
<Rectangle Width="150"
Height="150"
x:Name="myRectangle">
<Rectangle.Fill>
<LinearGradientBrush
StartPoint="0,0"
EndPoint="0,1" x:Name="myLinear
GradientBrush">
<GradientStop Color="red"
Offset="-1" x:Name=
"myGradientStop" />
<GradientStop Color=
"yellow"
Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName=
"myGradientStop"
Storyboard.TargetProperty=
"Offset"
From="-1" To="1"
Duration="0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Изменение границы распространения линейного градиента | ||
| № | Код | Вид в браузере |
| 7.3.8 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="150" Height="150"
Background="White"
x:Name="Page">
<Ellipse Width="150"
Height="150" >
<Ellipse.Fill>
<RadialGradientBrush>
<GradientStop Color="Red"
Offset="0" x:Name=
"myGradientStop" />
<GradientStop Color="Yellow"
Offset="1" />
</RadialGradientBrush>
</Ellipse.Fill>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="
Forever"
Storyboard.TargetName="
myGradientStop"
Storyboard.TargetProperty="Offset"
From="-1" To="1"
Duration="0:0:5" AutoReverse=
"True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Изменение границы распространения радиального градиента | ||
| № | Код | Вид в браузере |
| 7.3.9 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="150" Height="150"
Background="White"
x:Name="Page">
<Ellipse Width = "140"
Height="140"
Canvas.Left = "5"
Canvas.Top="5" Stroke="Red"
StrokeThickness="5"
x:Name="myEllipse" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="
Forever"
Storyboard.TargetName="myEllipse"
Storyboard.TargetProperty=
"StrokeThickness"
From="5" To="50"
Duration="0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Изменение ширины контура фигуры | ||
| № | Код | Описание |
| 7.3.10 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="70"
Background="White"
x:Name="Page">
<TextBlock
x:Name="myText"
FontFamily="Verdana"
FontSize="32"
FontWeight="Bold"
Foreground="Red">
XAML-графика
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName=
"myText"
Storyboard.TargetProperty=
"FontSize"
To="50" Duration=
"0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Canvas>
|
Изменение размера шрифта текста | |
| Вид в браузере | ||
(рис )
|
||
Элемент ColorAnimation применяется для последовательного изменения цвета заливки или контура фигуры:
<Ellipse Canvas.Left="20" Canvas.Top="10"
Width="160" Height="80" Fill="red" x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow" Duration="0:0:8" BeginTime="0:0:2"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
Мы видим, что атрибуты внутри этого элемента в точности такие же, как и в случае использования элемента DoubleAnimation. В табл. 7.4 приводятся подобные примеры.
| № | Код | Вид в браузере |
|---|---|---|
| 7.4.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200"
Height="100"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="20"
Canvas.Top="10" Width="160"
Height="80" Fill="red"
x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.
TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow" Duration="0:0:8"
BeginTime="0:0:2"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
Последовательный переход красного цвета заливки в желтый. Анимация начинается через две секунды после загрузки ролика ( BeginTime="0:0:2" ). После завершения фигура остается желтой ( FillBehavior="HoldEnd" ). |
||
| № | Код | Вид в браузере |
| 7.4.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="20"
Canvas.Top="10" Width="160"
Height="80" Fill="red"
x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.
TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow" Duration="0:0:8"
BeginTime="0:0:2"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Изменение цвета контура | ||
При изучении элемента Path мы узнали, что с его помощью можно описать практически любые кривые. Элемент PointAnimation предназначен для изменения положения опорных точек объекта Path с последовательным смещением всей кривой. В табл. 7.5 приводятся примеры анимации этого типа.
| № | Код | Вид в браузере |
|---|---|---|
| 7.5.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="250" Height="200"
Background="White"
x:Name="Page">
<!--Исходный объект Path
<Path Stretch="Fill"
Stroke="green"
StrokeThickness="3"
Canvas.Left="25"
Canvas.Top="25"
Data="M25,75 Q100,25 175,75" />-->
<Path Stroke="green"
StrokeThickness="3">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="25,75">
<QuadraticBezierSegment
x:Name="mySegment"
Point1="100,25"
Point2="175,75" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="
Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.
TargetName="mySegment"
Storyboard.TargetProperty=
"Point1"
From="100,25"
To="100,225"
Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
|
|
|
| Описание | ||
Координаты исходного элемента Path задаются следующим образом: Data="M25,75 Q100,25 175,75". При анимации используется запись кривой в виде набора тегов. Точка Point1 становится атрибутом, который изменяется в ходе анимации |
||
| № | Код | Вид в браузере |
| 7.5.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="250" Height="200"
Background="White"
x:Name="Page">
<!--Исходный объект Path
<Path Stretch="Fill"
Stroke="green"
StrokeThickness="3"
Canvas.Left="25"
Canvas.Top="25"
Data="M25,75 Q100,25 175,75" />-->
<Path Stroke="green"
StrokeThickness="3">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="25,75">
<QuadraticBezierSegment
x:Name="mySegment"
Point1="100,25"
Point2="175,75" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="
Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.
TargetName="mySegment"
Storyboard.TargetProperty="Point2"
From="175,75" To="
175,375" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
|
|
|
| Описание | ||
| Анимация атрибута Point2 | ||
В классической мультипликации (http://ru.wikipedia.org/wiki/Мультипликация) иллюзия движения достигается за счет смены рисунков с определенной частотой (обычно 24 кадра в секунду). Графический формат GIF – это наследник мультипликации. Движущееся изображение состоит из отдельных рисунков, которые затем собираются в один файл (рис. 7.1):
(рис 7.1) Создание GIF-рисунка в программе Ulead GIF Animator
Во всех рассматриваемых выше примерах мы использовали линейные изменения свойств. Фактически, мы задавали начальное и конечное значения, а все остальные вычисления среда брала на себя. Теперь мы приступим к рассмотрению средств XAML позволяющих использовать покадровую анимацию, аналогичную приведенному GIF-рисунку.
Элемент LinearDoubleKeyFrame позволяет "встраиваться" в линейную анимацию, задавая промежуточные значения свойств:
<Rectangle Canvas.Top="40" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames RepeatBehavior=
"Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame KeyTime="0:0:1"
Value="100" />
<LinearDoubleKeyFrame KeyTime="0:0:9"
Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
В этом примере прямоугольник сначала за одну секунду достигнет точки 100, а затем из нее будет в течение восьми секунд двигаться в точку 200. Здесь получаются три опорных точки – начальная, конечная и промежуточная. Заметим, однако, что перемещение прямоугольника между этими опорными точками по-прежнему осуществляется линейным образом. Корневой элемент анимации DoubleAnimation заменился элементом DoubleAnimationUsingKeyFrames. Для анимации с помощью элементов ColorAnimation, PointAnimation используется вставка элементов LinearColorKeyFrame и LinearPointKeyFrame. В табл.7.6 приводятся примеры с использованием линейных опорных кадров.
| № | Код | Вид в браузере |
|---|---|---|
| 7.6.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
RepeatBehavior="Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame KeyTime=
"0:0:1" Value="100" />
<LinearDoubleKeyFrame KeyTime="
0:0:9" Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
Изменение абсциссы прямоугольника. Начальное время для всех элементов LinearDoubleKeyFrame одинаковое. Это означает, что перемещение из точки 100 в точку 200 будет осуществляться не в течении 9 секунд, а 8 |
||
| № | Код | Вид в браузере |
| 7.6.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
RepeatBehavior="Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame Key
Time="0:0:3" Value="50" />
<LinearDoubleKeyFrame KeyTime="
0:0:4" Value="100" />
<LinearDoubleKeyFrame
KeyTime="0:0:7" Value="150" />
<LinearDoubleKeyFrame KeyTime="
0:0:8" Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Перемещение прямоугольника в четыре этапа. В течение первых трех секунд (KeyTime="0:0:3") происходит движение в точку 50. Затем за одну секунду (KeyTime="0:0:4") происходит рывок в точку 100. Затем снова три секунды медленного движения в точку 150 (KeyTime="0:0:7"). Завершает анимацию снова секундный рывок в точку 200 (KeyTime="0:0:8"). | ||
| № | Код | Вид в браузере |
| 7.6.3 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="20" Canvas.Top="10"
Width="160" Height="80" Fill="red"
x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.
TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
BeginTime="0:0:2"
FillBehavior="HoldEnd">
<LinearColorKeyFrame KeyTime="0:0:5"
Value="Orange" />
<LinearColorKeyFrame KeyTime="0:0:8"
Value="Yellow" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
Элемент ColorAnimation заменяется на ColorAnimationUsingKeyFrames. Здесь, в отличие от соответствующего примера без опорных кадров, мы однозначно указываем граничные цвета анимации |
||
| № | Код | Вид в браузере |
| 7.6.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="250" Height="200"
Background="White"
x:Name="Page">
<!--Исходный объект Path
<Path Stretch="Fill"
Stroke="green" StrokeThickness="3"
Canvas.Left="25" Canvas.Top="25"
Data="M25,75 Q100,25 175,75" />-->
<Path Stroke="green"
StrokeThickness="3">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="25,75">
<QuadraticBezierSegment
x:Name="mySegment"
Point1="100,25"
Point2="175,75" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="
Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimationUsingKeyFrames
Storyboard.TargetName="mySegment"
Storyboard.TargetProperty="Point1">
<LinearPointKeyFrame KeyTime="0:0:3"
Value="100,225" />
<LinearPointKeyFrame KeyTime="0:0:6"
Value="100,125" />
<LinearPointKeyFrame KeyTime="0:0:9"
Value="100,325" />
</PointAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
|
|
|
| Описание | ||
Элемент PointAnimation заменяется на PointAnimationUsingKeyFrames. Серия изменений кооринат точки Point1 сопровождается изменением формы всей фигуры |
||
В рассмотренных выше случаях использования линейных опорных кадров, также как и в линейной анимации, изменения свойств между промежуточными значениями осуществляется плавно. В случае использования дискретных опорных кадров переход между значениями осуществляется скачком. Здесь мы действительно имеем дело с отдельными кадрами, которым могут меняться совершенно независимо друг от друга. В табл. 7.7приводятся примеры подобных роликов.
| № | Код | Вид в браузере |
|---|---|---|
| 7.7.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="my
Rectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<DiscreteDoubleKeyFrame Key
Time="0:0:1" Value="100" />
<DiscreteDoubleKeyFrame Key
Time="0:0:3" Value="180" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| После загрузки, через одну секунду прямоугольник оказывается в точке 100. Затем спустя еще две секунды он перемещается в точку 180 | ||
| № | Код | Вид в браузере |
| 7.7.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="200"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="40" Canvas.
Top="10" Width="120" Height="80"
Fill="LightPink" Stroke="LightCoral"
StrokeThickness="4" x:Name="FirstEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="FirstEllipse"
Storyboard.TargetProperty="Height" >
<DiscreteDoubleKeyFrame
KeyTime="0:0:1" Value="80" />
<DiscreteDoubleKeyFrame KeyTime=
"0:0:3" Value="40" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<Ellipse Canvas.Left="40" Canvas.
Top="110" Width="120" Height="80"
Fill="Yellow" Stroke="Orange"
StrokeThickness="4" x:Name="
SecondEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="SecondEllipse"
Storyboard.TargetProperty="Height" >
<DiscreteDoubleKeyFrame Key
Time="0:0:1" Value="80" />
<DiscreteDoubleKeyFrame Key
Time="0:0:3" Value="40" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Использование дискретных опорных кадров для двух объектов. Эллипсы одновременно, скачком, меняют свои размеры | ||
Для поддержки элементов ColorAnimation, PointAnimation в случае дискретных опорных кадров используются элементы DiscreteColorKeyFrame и DiscretePointKeyFrame.
Представим себе автомобиль, стоящий на перекрестке. После того, как на светофоре появится зеленый свет, автомобиль начнет ускоряться. Достигнув положенных в городе 60 км.\ч, некоторое время он будет двигаться равномерно. Затем, подъезжая к следующему перекрестку, автомобиль начнет тормозить и полностью остановится.
Будем считать, что три участка – разгон, движение и торможение примерно равны между собой. Тогда общее перемещение автомобиля можно представить в виде кривой (сплайна) KeySpline="0.3,0 0.6,1". Здесь точки (0.3, 0) и (0.6,1) определяют квадратичную кривую Безье. Эта кривая нормализована так, что первой точкой кривой является 0.0, вторая 1.1. Пример анимации, использующий описанный сплайн, приводится в табл. 7.8.
| № | Код | Вид в браузере |
|---|---|---|
| 7.8.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Canvas.Left)" >
<SplineDoubleKeyFrame Key
Time="0:0:9"
KeySpline="0.3,0 0.6,1"
Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Прямоугольник разгоняется примерно до одной трети своего пути, затем треть двигается равномерно, а к концу начинает замедляться. При определении значений важно помнить, что координаты фигур по-прежнему отсчитываются относительно верхней левой точки | ||
Варьируя значения атрибута KeySpline можно получать различные варианты замедления и ускорения анимации.
Пакет Microsoft Expression Blend содержит визуальные средства для работы с анимацией. Сначала создадим уже знакомый нам прямоугольник, который и будем анимировать:
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="200" Height="100" Background="White" x:Name="Page"> <Rectangle Canvas.Left ="5" Canvas.Top="5" Width="190" Height="90" Stroke="green" StrokeThickness="2" Fill="Transparent" /> <Rectangle Canvas.Top="40" Width="20" Height="20" Fill="red" x:Name="myRectangle" > </Rectangle> </Canvas>
Лучше всего в главном меню выбрать пункт "Windows \ Active Workspace \ Animation Workspace" – вид редактора изменится, отображая нужные панели инструментов (рис. 7.2):
(рис 7.2) Рабочее пространство "Animation Workspace".
Создаем раскадровку, для чего на панели "Interaction" выбираем значение списка "New" (рис. 7.3):
(рис 7.3) Создание раскадровки (Storyboard).
В появившемся диалоговом окне "Create Storyboard" оставим предлагаемое название без изменений и снимаем галочку "Create as a Resource" (рис. 7.4):
(рис 7.4) Диалоговое окно "Create Storyboard".
Если бы мы оставили галочку "Create as a Resource", то запускать анимацию пришлось бы с помощью кода JavaScript. В следующей лекции мы рассмотрим, как это делать, а пока будем двигаться дальше. После создания раскадровки нужно определить стартовое положение анимации. Нажимаем на кнопку "Record Keyframe" (рис. 7.5):
(рис 7.5) Начало анимации
Можно сказать, что текущее расположение объектов (прямоугольника) автоматически будет стартовой позицией. Переносим головку воспроизведения на метку с цифрой 3 (рис. 7.6):
(рис 7.6) Завершение анимации
В результате этого действия мы определили конечную позицию анимации. Теперь непосредственно "хватаем" красный прямоугольник и перемещаем его. При этом на временной шкале автоматически появляется серая полоса (рис. 7.7.):
(рис 7.7) Перемещение объекта
Все, анимация готова. Ее можно увидеть при запуске проекта. Впрочем, воспроизвести движение объекта можно прямо в режиме разработки – для этого следует нажать на кнопку "Play" (рис. 7.8):
(рис 7.8) Воспроизведение анимации
Посмотрим код, который сгенерировал пакет Microsoft Expression Blend:
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).
(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="180"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
<Rectangle Canvas.Left ="5" Canvas.Top="5" Width="190"
Height="90" Stroke="green" StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Top="40" Width="20"
Height="20" Fill="red" x:Name="myRectangle"
RenderTransformOrigin="0.5,0.5" >
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
Отметим несколько особенностей:
Rectangle, а в описании Canvas.TranslateTransform.Рассматривая код предыдущего примера уже можно понять, как осуществляется анимация трансформаций. В принципе, ничего нового здесь нет – мы даем названия с помощью атрибута "x:Name", а затем указываем граничные значения заданного свойства. В табл. 7.9 приводятся подобные примеры.
| № | Код | Вид в браузере |
|---|---|---|
| 7.9.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="150"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left="10"
Canvas.Top="10" Width="50"
Height="25" Fill="skyblue"
Stroke="red" StrokeThickness="2"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="my
Transform" X="10" Y="10"/>
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="X"
From="10" To="180"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Перемещение прямоугольника в горизонтальном направлении | ||
| № | Код | Вид в браузере |
| 7.9.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="150"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left="10"
Canvas.Top="10" Width="50"
Height="25" Fill="skyblue"
Stroke="red" StrokeThickness="2"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="my
Transform" X="10" Y="10"/>
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="X"
From="10" To="180"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="
Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="Y"
From="10" To="130"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Одновременный перенос по оси X и Y будет формировать движение прямоугольника по диагонали | ||
| № | Код | Вид в браузере |
| 7.9.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="150"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left="25"
Canvas.Top="25" Width="50"
Height="25" Fill="skyblue"
Stroke="red"
StrokeThickness="2"/>
<Rectangle Canvas.Left="25"
Canvas.Top="50" Width="50"
Height="25" Fill="palegreen"
Stroke="red"
StrokeThickness="2" >
<Rectangle.RenderTransform>
<ScaleTransform x:Name="myTransform"
ScaleX="1" ScaleY="1" />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent=
"Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="ScaleX"
From="1" To="2"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Горизонтальное масштабирование | ||
| № | Код | Вид в браузере |
| 7.9.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="210"
Height="210"
Canvas.Left="0"
Canvas.Top="0">
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<RotateTransform x:Name="my
Transform" Angle="45"/>
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent=
"Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Repeat
Behavior="Forever"
Storyboard.TargetName=
"myTransform"
Storyboard.TargetProperty=
"Angle"
From="0"
To="360"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
Вращение фигуры относительно верхней левой точки элемента Canvas |
||
| № | Код | Вид в браузере |
| 7.9.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="200"
Height="200"
Canvas.Left="0"
Canvas.Top="0"
RenderTransformOrigin="1,1">
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="100"
Height="50"
Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<RotateTransform x:Name="my
Transform" Angle="45"/>
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="my
Transform"
Storyboard.TargetProperty=
"Angle"
From="0" To="360"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
Вращение фигуры относительно верхней левой точки. Выравнивание точки вращения было достигнуто с помощью атрибута RenderTransformOrigin="1,1" |
||
| № | Код | Вид в браузере |
| 7.9.7 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="200"
Height="200" Canvas.Left="0"
Canvas.Top="0"
RenderTransformOrigin="1,1">
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<SkewTransform x:Name="
myTransform" AngleY="45" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior
="Forever"
Storyboard.TargetName="my
Transform"
Storyboard.TargetProperty="AngleY"
From="0" To="60"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
| Смещение фигуры в вертикальном направлении | ||
| № | Код | Вид в браузере |
| 7.9.7 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="200"
Height="200"
Canvas.Left="0"
Canvas.Top="0"
RenderTransformOrigin="1,1">
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="100"
Height="50"
Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<TransformGroup>
<SkewTransform x:Name="
mySkewTransform" AngleY="45" />
<RotateTransform x:Name="
myRotateTransform" Angle="45"/>
</TransformGroup>
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="my
SkewTransform"
Storyboard.TargetProperty="AngleY"
From="0" To="60"
Duration="0:0:10"
AutoReverse="True" />
<DoubleAnimation Repeat
Behavior="Forever"
Storyboard.TargetName="myRotate
Transform"
Storyboard.TargetProperty="Angle"
From="0" To="360"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
| Комбинация преобразований – смещение фигуры с одновременным вращением | ||
Одна из самых интересных возможностей компьютерной анимации – это движение фигуры вдоль произвольно задаваемой траектории (рис. 7.9):
(рис 7.9) 1. Два отдельных объекта. 2. Эллипс становится траекторией движения. 3. Движение вдоль заданной траектории (иллюстрация из справки Microsoft Expression Blend)
В качестве траектории может использоваться не только замкнутая фигура, но и вообще, любая кривая, нарисованная, например, с помощью инструмента "Кисть". К сожалению, на момент написания этого курса, в Silverlight-проектах не поддерживается привязка движения к траектории. Однако эта возможность реализована в WPF-приложениях. Рассмотрим такой пример на практике. Создаем новый WPF – проект (рис. 7.10):
(рис 7.10) Создание нового WPF-приложения
Сначала нарисуем окружность, которая будет служить траекторией. Для этого выбираем инструмент эллипс и рисуем фигуру – можно даже без всякой заливки (рис. 7.11):
(рис 7.11) Рисование траектории
Теперь добавим окружность, которая и будет двигаться. Ее расположение на холсте, цвет заливки и оформления могут быть совершенно произвольными. Но на панели "Properties", в поле "Name " введем имя фигуры, например, "myBall" (рис. 7.12):
(рис 7.12) Фигура, которая будет двигаться по траектории, должна иметь заполненное значение поля Name
Выделяем исходный эллипс, который будет служить траекторией и в главном меню выбираем пункт "Object \ Path \ Convert to Motion Path" (рис. 7.13):
(рис 7.13) Пункт главного меню "Object \ Path \ Convert to Motion Path".
При этом происходит преобразование текущей кривой в траекторию движения. В появившемся диалоговом окне "Convert to Motion Path" нам нужно выбрать объект, который будет привязан к создаваемой траектории. Здесь мы указываем объект "myBall" (рис. 7.14):
(рис 7.14) Выбор привязываемого объекта
Практически все готово. Вид редактора Microsoft Expression Blend меняется – шарик перескакивает на свою стартовую позицию, причем его центр совмещен с траекторией (рис. 7.15):
(рис 7.15) Вид редактора Microsoft Expression Blend после завершения привязки объекта к траектории
Запускаем приложение, нажимая клавишу F5. Объект двигается по замкнутой траектории (рис. 7.16):
(рис 7.16) Готовое приложение
Если сделать направляющую нулевой толщины или установить для нее белый цвет контура, то она будет не видна. Дальнейшее оформление ограничено лишь фантазией разработчика. Код, сгенерированный средой, достаточно громоздок:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/
xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Motion_Path.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480">
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingPath BeginTime="00:00:00"
Duration="00:00:02" Storyboard.TargetName="myBall"
Storyboard.TargetProperty="(UIElement.RenderTransform).(
TransformGroup.Children)[3].
(TranslateTransform.X)" Source="X">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True"
StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1452138623941"
Point2="167.179268471912,86.5" Point3="75.5,86.5" IsSmoothJoin="True"/>
<BezierSegment Point1="-16.1792684719117,86.5"
Point2="-90.5,53.1452138623941" Point3="-90.5,12" IsSmoothJoin="True"/>
<BezierSegment Point1="-90.5,-29.1452138623941"
Point2="-16.1792684719117,-62.5" Point3="75.5,-62.5" IsSmoothJoin="True"/>
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1452138623941" Point3="241.5,12" IsSmoothJoin="True"/>
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath
BeginTime="00:00:00" Duration="00:00:02"
Storyboard.TargetName="myBall" Storyboard.
TargetProperty="(UIElement.RenderTransform).
(TransformGroup.Children)[3].(TranslateTransform.Y)" Source="Y">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1452138623941"
Point2="167.179268471912,86.5" Point3="75.5,86.5" IsSmoothJoin="True"/>
<BezierSegment Point1="-16.1792684719117,86.5"
Point2="-90.5,53.1452138623941" Point3="-90.5,12" IsSmoothJoin="True"/>
<BezierSegment Point1="-90.5,-29.1452138623941"
Point2="-16.1792684719117,-62.5" Point3="75.5,-62.5" IsSmoothJoin="True"/>
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1452138623941" Point3="241.5,12" IsSmoothJoin="True"/>
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Ellipse Margin="144,0,147,53" VerticalAlignment="Bottom"
Height="150" Fill="#FFFFFFFF" Stroke="#FF000000"/>
<Ellipse HorizontalAlignment="Left" Margin="210,0,0,115"
VerticalAlignment="Bottom" Width="50" Height="50"
Fill="#FFFF0000"
Stroke="#FF000000" x:Name="myBall" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
</Window>
Его можно упростить, если убрать дробные значения в координатах, а также удалить ненужные команды трансформации:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Motion_Path.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480">
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingPath BeginTime="00:00:00"
Duration="00:00:02" Storyboard.TargetName="myBall"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)" Source="X">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1"
Point2="167.1,86.5" Point3="75.5,86.5" />
<BezierSegment Point1="-16.1,86.5"
Point2="-90.5,53.1" Point3="-90.5,12" />
<BezierSegment Point1="-90.5,-29.1"
Point2="-16.1,-62.5" Point3="75.5,-62.5" />
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1" Point3="241.5,12" />
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath BeginTime="00:00:00"
Duration="00:00:02" Storyboard.TargetName="myBall" Storyboard.
TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)" Source="Y">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1"
Point2="167.1,86.5" Point3="75.5,86.5" />
<BezierSegment Point1="-16.1,86.5"
Point2="-90.5,53.1" Point3="-90.5,12" />
<BezierSegment Point1="-90.5,-29.1"
Point2="-16.1,-62.5" Point3="75.5,-62.5" />
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1" Point3="241.5,12" />
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Ellipse Margin="144,0,147,53" VerticalAlignment="Bottom"
Height="150" Fill="Transparent" Stroke="Black"/>
<Ellipse HorizontalAlignment="Left" Margin="210,0,0,115"
VerticalAlignment="Bottom" Width="50" Height="50"
Fill="Red" x:Name="myBall" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
</Window>
Здесь мы видим, что привязка к траектории, описываемая объектом Path, осуществляется дважды – для команды TranslateTransform.X и TranslateTransform.Y. Вместо данных, подставляемых в объект Path, можно подставлять свои значения, созданные без всяких визуальных средств.
Завершив изучение этой лекции, полезно прочитать статью Деклана Бреннана (Declan Brennan) "Создание сложной трехмерной анимации с помощью Silverlight 2.0" http://msdn.microsoft.com/ru-ru/magazine/cc500570.aspx.
Анимацию в XAML можно разделить на две категории – линейную, при которой свойство плавно меняется с течением времени и покадровую, напоминающую классическую мультипликацию. Элементы и атрибуты, описывающие код, практически одинаковы в обеих категориях. Рассмотрим сначала линейную анимацию.
Фрагмент кода, описывающий движение прямоугольника, выглядит так:
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)"
From="0" To="200"
Duration="0:0:01"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Анимация происходит в ответ на события. Эта концепция очень похожа на общую модель событий объектно-ориентированного программирования вообще и, например, языка C# в частности. События определяются при помощи триггеров здесь – в данном примере эту роль играет элемент Rectangle Triggers. Значение "Rectangle.Loaded" атрибута RoutedEvent элемента EventTrigger указывает на то, что анимация начнется сразу после загрузки прямоугольника. Далее при помощи тега BeginStoryboard (начать раскадровку) определяется раскадровка Storyboard. Именно в элементе Storyboard определяются свойства, которые и будут меняться с течением времени. Элемент DoubleAnimation указывает на то, что анимируемое свойство является числом (типа Double ). Это один из трех возможных типов, другие приводятся в табл. 7.1.
| Элемент | Описание |
|---|---|
DoubleAnimation |
Задание анимации свойства в виде числа (поддерживаются дробные значения). |
ColorAnimation |
Анимация изменения цвета |
PointAnimation |
Изменение координат точки, задаваемой с помощью элемента Path |
Описание анимируемого объекта задается с помощью атрибутов, перечень которых приводится в табл. 7.2.
| Элемент | Описание |
|---|---|
Storyboard.TargetName |
Название объекта, свойство которого будет анимироваться. Это название предварительно задается в описании самого объекта при помощи атрибута x:Name |
Storyboard.TargetProperty |
Название свойства (атрибута), которое будет изменяться |
From |
Начальное значение анимируемого свойства. Если в описании объекта уже указано нужное значение From, то в описании анимации этот атрибут можно опустить |
To |
Конечное значение анимируемого свойства |
Duration |
Продолжительность изменения анимируемого свойства в формате "часы : минуты : секунды". Это не общая продолжительность анимации. Например, если задать перемещение объекта из точки 0,0 в точку 200,200 и указать значение Duration ="0:0:01", то этот объект и будет двигаться в течении одной секунды. Однако сколько раз он так будет перемещаться, определяет атрибут RepeatBehavior |
RepeatBehavior |
Поведение объекта после завершения анимации или общая продолжительность анимации. Возможны следующие значение: |
AutoReverse |
Автоматическое обращения воспроизведения, возможные значения "True" и "False" (по умолчанию). Например, если задать перемещение объекта из точки 0,0 в точку 200,200 и задать AutoReverse=" True ", то при достижении точки 200, 200 объект будет двигаться в обратном направлении |
By |
Относительное конечное значение анимируемого свойства. Например, если задать перемещение объекта из точки 100 в точку 300, то это можно сделать так:From="100" To="300" В этом случае происходит относительное смещение на 200 единиц. С помощью атрибута From="0" By="200" При одновременно задании обоих свойств To будет иметь больший приоритет, а |
BeginTime |
Задание времени старта анимации. Например, при значении BeginTime="0:0:3" анимация начнет воспроизводиться спустя три секунды |
SpeedRatio |
Коэффициент скорости. Предположим, что была установлено пятисекундное изменение некоторого свойства: Duration ="0:0:05". Это значение можно увеличить до 10 секунд, если указать SpeedRatio="0.5". Наоборот, при значении SpeedRatio="2" воспроизведение сократится до двух с половиной секунд |
Несмотря на большое количество атрибутов, отметим, что для создания анимации достаточно всего несколько ключевых значений.
Элемент DoubleAnimation позволяет анимировать числовые (включая дробные) значения свойств. Это означает, что с помощью этого элемента можно изменять наибольшее количество свойств объектов. В самом деле – координаты, размеры, прозрачность, направление градиента – все эти параметры задаются в виде чисел. В табл. 7.3 приводятся различные примеры с элементом DoubleAnimation.
| № | Код | Вид в браузере |
|---|---|---|
| 7.3.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="
Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle
.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="my
Rectangle"
Storyboard.TargetProperty="
(Canvas.Left)"
From="0" To="200"
Duration="0:0:01"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
Изменение абсциссы прямоугольника. Значение "Canvas.Left" атрибута Storyboard.TargetProperty было взято в скобки, поскольку оно состоит из двух слов. Анимация будет воспроизводиться бесконечно ( RepeatBehavior="Forever" ), а прямоугольник будет курсировать от одной точки к другой и обратно ( AutoReverse="True" ). |
||
| № | Код | Вид в браузере |
| 7.3.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="3x"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="
(Canvas.Left)"
From="0" To="200"
Duration="0:0:01"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
Трехкратное повторение анимации за счет свойства RepeatBehavior="3x". |
||
| № | Код | Вид в браузере |
| 7.3.3 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="90"
Canvas.Top="40" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="
(Canvas.Top)"
From="0" To="100"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Изменение ординаты прямоугольника | ||
| № | Код | Вид в браузере |
| 7.3.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="0"
Canvas.Top="40" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent=
"Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="
myRectangle"
Storyboard.TargetProperty="
(Canvas.Top)"
From="0" To="100"
Duration="0:0:05"
AutoReverse="True" />
<DoubleAnimation
RepeatBehavior="3x"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Canvas.Left)"
From="0" To="200"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Одновременное увеличение абсциссы и ординаты, в результате чего прямоугольник будет двигаться по диагонали | ||
| № | Код | Вид в браузере |
| 7.3.5 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
RepeatBehavior="Forever"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Width)"
From="0" To="195"
Duration="0:0:05"
AutoReverse="True" />
<DoubleAnimation RepeatBehavior=
"3x"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Height)"
From="0"
To="95"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Одновременное увеличение ширины и высоты прямоугольника | ||
| № | Код | Вид в браузере |
| 7.3.6 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Left ="10"
Canvas.Top="10" Width="180"
Height="80" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Rectangle.Opacity)"
From="1" To="0"
Duration="0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Изменение прозрачности фигуры | ||
| № | Код | Вид в браузере |
| 7.3.7 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="150" Height="150"
Background="White"
x:Name="Page">
<Rectangle Width="150"
Height="150"
x:Name="myRectangle">
<Rectangle.Fill>
<LinearGradientBrush
StartPoint="0,0"
EndPoint="0,1" x:Name="myLinear
GradientBrush">
<GradientStop Color="red"
Offset="-1" x:Name=
"myGradientStop" />
<GradientStop Color=
"yellow"
Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName=
"myGradientStop"
Storyboard.TargetProperty=
"Offset"
From="-1" To="1"
Duration="0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Изменение границы распространения линейного градиента | ||
| № | Код | Вид в браузере |
| 7.3.8 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="150" Height="150"
Background="White"
x:Name="Page">
<Ellipse Width="150"
Height="150" >
<Ellipse.Fill>
<RadialGradientBrush>
<GradientStop Color="Red"
Offset="0" x:Name=
"myGradientStop" />
<GradientStop Color="Yellow"
Offset="1" />
</RadialGradientBrush>
</Ellipse.Fill>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="
Forever"
Storyboard.TargetName="
myGradientStop"
Storyboard.TargetProperty="Offset"
From="-1" To="1"
Duration="0:0:5" AutoReverse=
"True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Изменение границы распространения радиального градиента | ||
| № | Код | Вид в браузере |
| 7.3.9 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="150" Height="150"
Background="White"
x:Name="Page">
<Ellipse Width = "140"
Height="140"
Canvas.Left = "5"
Canvas.Top="5" Stroke="Red"
StrokeThickness="5"
x:Name="myEllipse" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="
Forever"
Storyboard.TargetName="myEllipse"
Storyboard.TargetProperty=
"StrokeThickness"
From="5" To="50"
Duration="0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Изменение ширины контура фигуры | ||
| № | Код | Описание |
| 7.3.10 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="70"
Background="White"
x:Name="Page">
<TextBlock
x:Name="myText"
FontFamily="Verdana"
FontSize="32"
FontWeight="Bold"
Foreground="Red">
XAML-графика
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName=
"myText"
Storyboard.TargetProperty=
"FontSize"
To="50" Duration=
"0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Canvas>
|
Изменение размера шрифта текста | |
| Вид в браузере | ||
(рис )
|
||
Элемент ColorAnimation применяется для последовательного изменения цвета заливки или контура фигуры:
<Ellipse Canvas.Left="20" Canvas.Top="10"
Width="160" Height="80" Fill="red" x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow" Duration="0:0:8" BeginTime="0:0:2"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
Мы видим, что атрибуты внутри этого элемента в точности такие же, как и в случае использования элемента DoubleAnimation. В табл. 7.4 приводятся подобные примеры.
| № | Код | Вид в браузере |
|---|---|---|
| 7.4.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200"
Height="100"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="20"
Canvas.Top="10" Width="160"
Height="80" Fill="red"
x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.
TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow" Duration="0:0:8"
BeginTime="0:0:2"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
Последовательный переход красного цвета заливки в желтый. Анимация начинается через две секунды после загрузки ролика ( BeginTime="0:0:2" ). После завершения фигура остается желтой ( FillBehavior="HoldEnd" ). |
||
| № | Код | Вид в браузере |
| 7.4.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="20"
Canvas.Top="10" Width="160"
Height="80" Fill="red"
x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.
TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow" Duration="0:0:8"
BeginTime="0:0:2"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Изменение цвета контура | ||
При изучении элемента Path мы узнали, что с его помощью можно описать практически любые кривые. Элемент PointAnimation предназначен для изменения положения опорных точек объекта Path с последовательным смещением всей кривой. В табл. 7.5 приводятся примеры анимации этого типа.
| № | Код | Вид в браузере |
|---|---|---|
| 7.5.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="250" Height="200"
Background="White"
x:Name="Page">
<!--Исходный объект Path
<Path Stretch="Fill"
Stroke="green"
StrokeThickness="3"
Canvas.Left="25"
Canvas.Top="25"
Data="M25,75 Q100,25 175,75" />-->
<Path Stroke="green"
StrokeThickness="3">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="25,75">
<QuadraticBezierSegment
x:Name="mySegment"
Point1="100,25"
Point2="175,75" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="
Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.
TargetName="mySegment"
Storyboard.TargetProperty=
"Point1"
From="100,25"
To="100,225"
Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
|
|
|
| Описание | ||
Координаты исходного элемента Path задаются следующим образом: Data="M25,75 Q100,25 175,75". При анимации используется запись кривой в виде набора тегов. Точка Point1 становится атрибутом, который изменяется в ходе анимации |
||
| № | Код | Вид в браузере |
| 7.5.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="250" Height="200"
Background="White"
x:Name="Page">
<!--Исходный объект Path
<Path Stretch="Fill"
Stroke="green"
StrokeThickness="3"
Canvas.Left="25"
Canvas.Top="25"
Data="M25,75 Q100,25 175,75" />-->
<Path Stroke="green"
StrokeThickness="3">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="25,75">
<QuadraticBezierSegment
x:Name="mySegment"
Point1="100,25"
Point2="175,75" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="
Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.
TargetName="mySegment"
Storyboard.TargetProperty="Point2"
From="175,75" To="
175,375" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
|
|
|
| Описание | ||
| Анимация атрибута Point2 | ||
В классической мультипликации (http://ru.wikipedia.org/wiki/Мультипликация) иллюзия движения достигается за счет смены рисунков с определенной частотой (обычно 24 кадра в секунду). Графический формат GIF – это наследник мультипликации. Движущееся изображение состоит из отдельных рисунков, которые затем собираются в один файл (рис. 7.1):
(рис 7.1) Создание GIF-рисунка в программе Ulead GIF Animator
Во всех рассматриваемых выше примерах мы использовали линейные изменения свойств. Фактически, мы задавали начальное и конечное значения, а все остальные вычисления среда брала на себя. Теперь мы приступим к рассмотрению средств XAML позволяющих использовать покадровую анимацию, аналогичную приведенному GIF-рисунку.
Элемент LinearDoubleKeyFrame позволяет "встраиваться" в линейную анимацию, задавая промежуточные значения свойств:
<Rectangle Canvas.Top="40" Width="20"
Height="20" Fill="red"
x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames RepeatBehavior=
"Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame KeyTime="0:0:1"
Value="100" />
<LinearDoubleKeyFrame KeyTime="0:0:9"
Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
В этом примере прямоугольник сначала за одну секунду достигнет точки 100, а затем из нее будет в течение восьми секунд двигаться в точку 200. Здесь получаются три опорных точки – начальная, конечная и промежуточная. Заметим, однако, что перемещение прямоугольника между этими опорными точками по-прежнему осуществляется линейным образом. Корневой элемент анимации DoubleAnimation заменился элементом DoubleAnimationUsingKeyFrames. Для анимации с помощью элементов ColorAnimation, PointAnimation используется вставка элементов LinearColorKeyFrame и LinearPointKeyFrame. В табл.7.6 приводятся примеры с использованием линейных опорных кадров.
| № | Код | Вид в браузере |
|---|---|---|
| 7.6.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.
Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
RepeatBehavior="Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame KeyTime=
"0:0:1" Value="100" />
<LinearDoubleKeyFrame KeyTime="
0:0:9" Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
Изменение абсциссы прямоугольника. Начальное время для всех элементов LinearDoubleKeyFrame одинаковое. Это означает, что перемещение из точки 100 в точку 200 будет осуществляться не в течении 9 секунд, а 8 |
||
| № | Код | Вид в браузере |
| 7.6.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
RepeatBehavior="Forever"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame Key
Time="0:0:3" Value="50" />
<LinearDoubleKeyFrame KeyTime="
0:0:4" Value="100" />
<LinearDoubleKeyFrame
KeyTime="0:0:7" Value="150" />
<LinearDoubleKeyFrame KeyTime="
0:0:8" Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Перемещение прямоугольника в четыре этапа. В течение первых трех секунд (KeyTime="0:0:3") происходит движение в точку 50. Затем за одну секунду (KeyTime="0:0:4") происходит рывок в точку 100. Затем снова три секунды медленного движения в точку 150 (KeyTime="0:0:7"). Завершает анимацию снова секундный рывок в точку 200 (KeyTime="0:0:8"). | ||
| № | Код | Вид в браузере |
| 7.6.3 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="20" Canvas.Top="10"
Width="160" Height="80" Fill="red"
x:Name="myEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.
TargetName="myEllipse"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
BeginTime="0:0:2"
FillBehavior="HoldEnd">
<LinearColorKeyFrame KeyTime="0:0:5"
Value="Orange" />
<LinearColorKeyFrame KeyTime="0:0:8"
Value="Yellow" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
Элемент ColorAnimation заменяется на ColorAnimationUsingKeyFrames. Здесь, в отличие от соответствующего примера без опорных кадров, мы однозначно указываем граничные цвета анимации |
||
| № | Код | Вид в браузере |
| 7.6.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="250" Height="200"
Background="White"
x:Name="Page">
<!--Исходный объект Path
<Path Stretch="Fill"
Stroke="green" StrokeThickness="3"
Canvas.Left="25" Canvas.Top="25"
Data="M25,75 Q100,25 175,75" />-->
<Path Stroke="green"
StrokeThickness="3">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="25,75">
<QuadraticBezierSegment
x:Name="mySegment"
Point1="100,25"
Point2="175,75" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="
Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimationUsingKeyFrames
Storyboard.TargetName="mySegment"
Storyboard.TargetProperty="Point1">
<LinearPointKeyFrame KeyTime="0:0:3"
Value="100,225" />
<LinearPointKeyFrame KeyTime="0:0:6"
Value="100,125" />
<LinearPointKeyFrame KeyTime="0:0:9"
Value="100,325" />
</PointAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
|
|
|
| Описание | ||
Элемент PointAnimation заменяется на PointAnimationUsingKeyFrames. Серия изменений кооринат точки Point1 сопровождается изменением формы всей фигуры |
||
В рассмотренных выше случаях использования линейных опорных кадров, также как и в линейной анимации, изменения свойств между промежуточными значениями осуществляется плавно. В случае использования дискретных опорных кадров переход между значениями осуществляется скачком. Здесь мы действительно имеем дело с отдельными кадрами, которым могут меняться совершенно независимо друг от друга. В табл. 7.7приводятся примеры подобных роликов.
| № | Код | Вид в браузере |
|---|---|---|
| 7.7.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="my
Rectangle"
Storyboard.TargetProperty="(Canvas.Left)" >
<DiscreteDoubleKeyFrame Key
Time="0:0:1" Value="100" />
<DiscreteDoubleKeyFrame Key
Time="0:0:3" Value="180" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| После загрузки, через одну секунду прямоугольник оказывается в точке 100. Затем спустя еще две секунды он перемещается в точку 180 | ||
| № | Код | Вид в браузере |
| 7.7.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="200"
Background="White"
x:Name="Page">
<Ellipse Canvas.Left="40" Canvas.
Top="10" Width="120" Height="80"
Fill="LightPink" Stroke="LightCoral"
StrokeThickness="4" x:Name="FirstEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="FirstEllipse"
Storyboard.TargetProperty="Height" >
<DiscreteDoubleKeyFrame
KeyTime="0:0:1" Value="80" />
<DiscreteDoubleKeyFrame KeyTime=
"0:0:3" Value="40" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<Ellipse Canvas.Left="40" Canvas.
Top="110" Width="120" Height="80"
Fill="Yellow" Stroke="Orange"
StrokeThickness="4" x:Name="
SecondEllipse">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="SecondEllipse"
Storyboard.TargetProperty="Height" >
<DiscreteDoubleKeyFrame Key
Time="0:0:1" Value="80" />
<DiscreteDoubleKeyFrame Key
Time="0:0:3" Value="40" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>
|
|
|
| Описание | ||
| Использование дискретных опорных кадров для двух объектов. Эллипсы одновременно, скачком, меняют свои размеры | ||
Для поддержки элементов ColorAnimation, PointAnimation в случае дискретных опорных кадров используются элементы DiscreteColorKeyFrame и DiscretePointKeyFrame.
Представим себе автомобиль, стоящий на перекрестке. После того, как на светофоре появится зеленый свет, автомобиль начнет ускоряться. Достигнув положенных в городе 60 км.\ч, некоторое время он будет двигаться равномерно. Затем, подъезжая к следующему перекрестку, автомобиль начнет тормозить и полностью остановится.
Будем считать, что три участка – разгон, движение и торможение примерно равны между собой. Тогда общее перемещение автомобиля можно представить в виде кривой (сплайна) KeySpline="0.3,0 0.6,1". Здесь точки (0.3, 0) и (0.6,1) определяют квадратичную кривую Безье. Эта кривая нормализована так, что первой точкой кривой является 0.0, вторая 1.1. Пример анимации, использующий описанный сплайн, приводится в табл. 7.8.
| № | Код | Вид в браузере |
|---|---|---|
| 7.8.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left ="5"
Canvas.Top="5" Width="190"
Height="90" Stroke="green"
StrokeThickness="2" Fill="Transparent" />
<Rectangle Canvas.Top="40"
Width="20" Height="20"
Fill="red" x:Name="myRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName=
"myRectangle"
Storyboard.TargetProperty=
"(Canvas.Left)" >
<SplineDoubleKeyFrame Key
Time="0:0:9"
KeySpline="0.3,0 0.6,1"
Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Прямоугольник разгоняется примерно до одной трети своего пути, затем треть двигается равномерно, а к концу начинает замедляться. При определении значений важно помнить, что координаты фигур по-прежнему отсчитываются относительно верхней левой точки | ||
Варьируя значения атрибута KeySpline можно получать различные варианты замедления и ускорения анимации.
Пакет Microsoft Expression Blend содержит визуальные средства для работы с анимацией. Сначала создадим уже знакомый нам прямоугольник, который и будем анимировать:
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="200" Height="100" Background="White" x:Name="Page"> <Rectangle Canvas.Left ="5" Canvas.Top="5" Width="190" Height="90" Stroke="green" StrokeThickness="2" Fill="Transparent" /> <Rectangle Canvas.Top="40" Width="20" Height="20" Fill="red" x:Name="myRectangle" > </Rectangle> </Canvas>
Лучше всего в главном меню выбрать пункт "Windows \ Active Workspace \ Animation Workspace" – вид редактора изменится, отображая нужные панели инструментов (рис. 7.2):
(рис 7.2) Рабочее пространство "Animation Workspace".
Создаем раскадровку, для чего на панели "Interaction" выбираем значение списка "New" (рис. 7.3):
(рис 7.3) Создание раскадровки (Storyboard).
В появившемся диалоговом окне "Create Storyboard" оставим предлагаемое название без изменений и снимаем галочку "Create as a Resource" (рис. 7.4):
(рис 7.4) Диалоговое окно "Create Storyboard".
Если бы мы оставили галочку "Create as a Resource", то запускать анимацию пришлось бы с помощью кода JavaScript. В следующей лекции мы рассмотрим, как это делать, а пока будем двигаться дальше. После создания раскадровки нужно определить стартовое положение анимации. Нажимаем на кнопку "Record Keyframe" (рис. 7.5):
(рис 7.5) Начало анимации
Можно сказать, что текущее расположение объектов (прямоугольника) автоматически будет стартовой позицией. Переносим головку воспроизведения на метку с цифрой 3 (рис. 7.6):
(рис 7.6) Завершение анимации
В результате этого действия мы определили конечную позицию анимации. Теперь непосредственно "хватаем" красный прямоугольник и перемещаем его. При этом на временной шкале автоматически появляется серая полоса (рис. 7.7.):
(рис 7.7) Перемещение объекта
Все, анимация готова. Ее можно увидеть при запуске проекта. Впрочем, воспроизвести движение объекта можно прямо в режиме разработки – для этого следует нажать на кнопку "Play" (рис. 7.8):
(рис 7.8) Воспроизведение анимации
Посмотрим код, который сгенерировал пакет Microsoft Expression Blend:
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="100"
Background="White"
x:Name="Page">
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).
(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="180"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
<Rectangle Canvas.Left ="5" Canvas.Top="5" Width="190"
Height="90" Stroke="green" StrokeThickness="2"
Fill="Transparent" />
<Rectangle Canvas.Top="40" Width="20"
Height="20" Fill="red" x:Name="myRectangle"
RenderTransformOrigin="0.5,0.5" >
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
Отметим несколько особенностей:
Rectangle, а в описании Canvas.TranslateTransform.Рассматривая код предыдущего примера уже можно понять, как осуществляется анимация трансформаций. В принципе, ничего нового здесь нет – мы даем названия с помощью атрибута "x:Name", а затем указываем граничные значения заданного свойства. В табл. 7.9 приводятся подобные примеры.
| № | Код | Вид в браузере |
|---|---|---|
| 7.9.1 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="150"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left="10"
Canvas.Top="10" Width="50"
Height="25" Fill="skyblue"
Stroke="red" StrokeThickness="2"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="my
Transform" X="10" Y="10"/>
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="X"
From="10" To="180"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Перемещение прямоугольника в горизонтальном направлении | ||
| № | Код | Вид в браузере |
| 7.9.2 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="150"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left="10"
Canvas.Top="10" Width="50"
Height="25" Fill="skyblue"
Stroke="red" StrokeThickness="2"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="my
Transform" X="10" Y="10"/>
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="X"
From="10" To="180"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="
Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="Y"
From="10" To="130"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Одновременный перенос по оси X и Y будет формировать движение прямоугольника по диагонали | ||
| № | Код | Вид в браузере |
| 7.9.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="200" Height="150"
Background="White"
x:Name="Page">
<Rectangle Canvas.Left="25"
Canvas.Top="25" Width="50"
Height="25" Fill="skyblue"
Stroke="red"
StrokeThickness="2"/>
<Rectangle Canvas.Left="25"
Canvas.Top="50" Width="50"
Height="25" Fill="palegreen"
Stroke="red"
StrokeThickness="2" >
<Rectangle.RenderTransform>
<ScaleTransform x:Name="myTransform"
ScaleX="1" ScaleY="1" />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent=
"Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="ScaleX"
From="1" To="2"
Duration="0:0:05"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
|
|
|
| Описание | ||
| Горизонтальное масштабирование | ||
| № | Код | Вид в браузере |
| 7.9.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="210"
Height="210"
Canvas.Left="0"
Canvas.Top="0">
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<RotateTransform x:Name="my
Transform" Angle="45"/>
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent=
"Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Repeat
Behavior="Forever"
Storyboard.TargetName=
"myTransform"
Storyboard.TargetProperty=
"Angle"
From="0"
To="360"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
Вращение фигуры относительно верхней левой точки элемента Canvas |
||
| № | Код | Вид в браузере |
| 7.9.4 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="200"
Height="200"
Canvas.Left="0"
Canvas.Top="0"
RenderTransformOrigin="1,1">
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="100"
Height="50"
Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<RotateTransform x:Name="my
Transform" Angle="45"/>
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="my
Transform"
Storyboard.TargetProperty=
"Angle"
From="0" To="360"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
Вращение фигуры относительно верхней левой точки. Выравнивание точки вращения было достигнуто с помощью атрибута RenderTransformOrigin="1,1" |
||
| № | Код | Вид в браузере |
| 7.9.7 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="200"
Height="200" Canvas.Left="0"
Canvas.Top="0"
RenderTransformOrigin="1,1">
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25" Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<SkewTransform x:Name="
myTransform" AngleY="45" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior
="Forever"
Storyboard.TargetName="my
Transform"
Storyboard.TargetProperty="AngleY"
From="0" To="60"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
| Смещение фигуры в вертикальном направлении | ||
| № | Код | Вид в браузере |
| 7.9.7 | ||
<Canvas
xmlns="http://schemas.microsoft.com/
client/2007"
xmlns:x="http://schemas.microsoft.com/
winfx/2006/xaml"
Width="400" Height="400"
Background="White"
x:Name="Page">
<!--Исходная фигура-->
<Rectangle Canvas.Left="200"
Canvas.Top="200" Width="100"
Height="50" Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<!--Повернутая фигура-->
<Canvas Width="200"
Height="200"
Canvas.Left="0"
Canvas.Top="0"
RenderTransformOrigin="1,1">
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="100"
Height="50"
Fill="yellow"
Stroke="red"
StrokeThickness="4"/>
<Rectangle Canvas.Left="200"
Canvas.Top="200"
Width="50"
Height="25"
Fill="green"
Stroke="red"
StrokeThickness="4" />
<Canvas.RenderTransform>
<TransformGroup>
<SkewTransform x:Name="
mySkewTransform" AngleY="45" />
<RotateTransform x:Name="
myRotateTransform" Angle="45"/>
</TransformGroup>
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="
Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior=
"Forever"
Storyboard.TargetName="my
SkewTransform"
Storyboard.TargetProperty="AngleY"
From="0" To="60"
Duration="0:0:10"
AutoReverse="True" />
<DoubleAnimation Repeat
Behavior="Forever"
Storyboard.TargetName="myRotate
Transform"
Storyboard.TargetProperty="Angle"
From="0" To="360"
Duration="0:0:10"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</Canvas>
|
|
|
| Описание | ||
| Комбинация преобразований – смещение фигуры с одновременным вращением | ||
Одна из самых интересных возможностей компьютерной анимации – это движение фигуры вдоль произвольно задаваемой траектории (рис. 7.9):
(рис 7.9) 1. Два отдельных объекта. 2. Эллипс становится траекторией движения. 3. Движение вдоль заданной траектории (иллюстрация из справки Microsoft Expression Blend)
В качестве траектории может использоваться не только замкнутая фигура, но и вообще, любая кривая, нарисованная, например, с помощью инструмента "Кисть". К сожалению, на момент написания этого курса, в Silverlight-проектах не поддерживается привязка движения к траектории. Однако эта возможность реализована в WPF-приложениях. Рассмотрим такой пример на практике. Создаем новый WPF – проект (рис. 7.10):
(рис 7.10) Создание нового WPF-приложения
Сначала нарисуем окружность, которая будет служить траекторией. Для этого выбираем инструмент эллипс и рисуем фигуру – можно даже без всякой заливки (рис. 7.11):
(рис 7.11) Рисование траектории
Теперь добавим окружность, которая и будет двигаться. Ее расположение на холсте, цвет заливки и оформления могут быть совершенно произвольными. Но на панели "Properties", в поле "Name " введем имя фигуры, например, "myBall" (рис. 7.12):
(рис 7.12) Фигура, которая будет двигаться по траектории, должна иметь заполненное значение поля Name
Выделяем исходный эллипс, который будет служить траекторией и в главном меню выбираем пункт "Object \ Path \ Convert to Motion Path" (рис. 7.13):
(рис 7.13) Пункт главного меню "Object \ Path \ Convert to Motion Path".
При этом происходит преобразование текущей кривой в траекторию движения. В появившемся диалоговом окне "Convert to Motion Path" нам нужно выбрать объект, который будет привязан к создаваемой траектории. Здесь мы указываем объект "myBall" (рис. 7.14):
(рис 7.14) Выбор привязываемого объекта
Практически все готово. Вид редактора Microsoft Expression Blend меняется – шарик перескакивает на свою стартовую позицию, причем его центр совмещен с траекторией (рис. 7.15):
(рис 7.15) Вид редактора Microsoft Expression Blend после завершения привязки объекта к траектории
Запускаем приложение, нажимая клавишу F5. Объект двигается по замкнутой траектории (рис. 7.16):
(рис 7.16) Готовое приложение
Если сделать направляющую нулевой толщины или установить для нее белый цвет контура, то она будет не видна. Дальнейшее оформление ограничено лишь фантазией разработчика. Код, сгенерированный средой, достаточно громоздок:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/
xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Motion_Path.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480">
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingPath BeginTime="00:00:00"
Duration="00:00:02" Storyboard.TargetName="myBall"
Storyboard.TargetProperty="(UIElement.RenderTransform).(
TransformGroup.Children)[3].
(TranslateTransform.X)" Source="X">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True"
StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1452138623941"
Point2="167.179268471912,86.5" Point3="75.5,86.5" IsSmoothJoin="True"/>
<BezierSegment Point1="-16.1792684719117,86.5"
Point2="-90.5,53.1452138623941" Point3="-90.5,12" IsSmoothJoin="True"/>
<BezierSegment Point1="-90.5,-29.1452138623941"
Point2="-16.1792684719117,-62.5" Point3="75.5,-62.5" IsSmoothJoin="True"/>
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1452138623941" Point3="241.5,12" IsSmoothJoin="True"/>
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath
BeginTime="00:00:00" Duration="00:00:02"
Storyboard.TargetName="myBall" Storyboard.
TargetProperty="(UIElement.RenderTransform).
(TransformGroup.Children)[3].(TranslateTransform.Y)" Source="Y">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1452138623941"
Point2="167.179268471912,86.5" Point3="75.5,86.5" IsSmoothJoin="True"/>
<BezierSegment Point1="-16.1792684719117,86.5"
Point2="-90.5,53.1452138623941" Point3="-90.5,12" IsSmoothJoin="True"/>
<BezierSegment Point1="-90.5,-29.1452138623941"
Point2="-16.1792684719117,-62.5" Point3="75.5,-62.5" IsSmoothJoin="True"/>
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1452138623941" Point3="241.5,12" IsSmoothJoin="True"/>
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Ellipse Margin="144,0,147,53" VerticalAlignment="Bottom"
Height="150" Fill="#FFFFFFFF" Stroke="#FF000000"/>
<Ellipse HorizontalAlignment="Left" Margin="210,0,0,115"
VerticalAlignment="Bottom" Width="50" Height="50"
Fill="#FFFF0000"
Stroke="#FF000000" x:Name="myBall" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
</Window>
Его можно упростить, если убрать дробные значения в координатах, а также удалить ненужные команды трансформации:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Motion_Path.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480">
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingPath BeginTime="00:00:00"
Duration="00:00:02" Storyboard.TargetName="myBall"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)" Source="X">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1"
Point2="167.1,86.5" Point3="75.5,86.5" />
<BezierSegment Point1="-16.1,86.5"
Point2="-90.5,53.1" Point3="-90.5,12" />
<BezierSegment Point1="-90.5,-29.1"
Point2="-16.1,-62.5" Point3="75.5,-62.5" />
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1" Point3="241.5,12" />
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath BeginTime="00:00:00"
Duration="00:00:02" Storyboard.TargetName="myBall" Storyboard.
TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)" Source="Y">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="241.5,12">
<BezierSegment Point1="241.5,53.1"
Point2="167.1,86.5" Point3="75.5,86.5" />
<BezierSegment Point1="-16.1,86.5"
Point2="-90.5,53.1" Point3="-90.5,12" />
<BezierSegment Point1="-90.5,-29.1"
Point2="-16.1,-62.5" Point3="75.5,-62.5" />
<BezierSegment Point1="167.179268471912,-62.5"
Point2="241.5,-29.1" Point3="241.5,12" />
</PathFigure>
</PathGeometry>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Ellipse Margin="144,0,147,53" VerticalAlignment="Bottom"
Height="150" Fill="Transparent" Stroke="Black"/>
<Ellipse HorizontalAlignment="Left" Margin="210,0,0,115"
VerticalAlignment="Bottom" Width="50" Height="50"
Fill="Red" x:Name="myBall" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
</Window>
Здесь мы видим, что привязка к траектории, описываемая объектом Path, осуществляется дважды – для команды TranslateTransform.X и TranslateTransform.Y. Вместо данных, подставляемых в объект Path, можно подставлять свои значения, созданные без всяких визуальных средств.
Завершив изучение этой лекции, полезно прочитать статью Деклана Бреннана (Declan Brennan) "Создание сложной трехмерной анимации с помощью Silverlight 2.0" http://msdn.microsoft.com/ru-ru/magazine/cc500570.aspx.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.