Спонсор: Microsoft
Опубликован: 23.01.2009 | Уровень: для всех | Доступ: платный
Лекция 7:

Анимация в XAML-графике

Анимация в Microsoft Expression Blend

Пакет 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):

Рабочее пространство "Animation Workspace".

увеличить изображение
Рис. 7.2. Рабочее пространство "Animation Workspace".

Создаем раскадровку, для чего на панели "Interaction" выбираем значение списка "New" (рис. 7.3):

Создание раскадровки (Storyboard).

Рис. 7.3. Создание раскадровки (Storyboard).

В появившемся диалоговом окне "Create Storyboard" оставим предлагаемое название без изменений и снимаем галочку "Create as a Resource" (рис. 7.4):

Диалоговое окно "Create Storyboard".

Рис. 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. Анимация трансформаций
Код Вид в браузере
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>

Описание
Комбинация преобразований – смещение фигуры с одновременным вращением
Илья Столупин
Илья Столупин
Россия
Олег Борхаленко
Олег Борхаленко
Украина