В лекц. 4, "Основы XAML", вы научились с помощью XAML формировать визуальное представление графических элементов на экране, будь то векторная графика, растровые изображения (с помощью объекта Image ) или видео. В данной лекции будет рассмотрено, как улучшить представление этих графических элементов с помощью различных типов трансформаций (для изменения их вида) и анимации (для изменения атрибутов объекта во времени). Кроме того, будет представлена анимация по ключевым кадрам и описано их использование при создании более сложного поведения. В завершение мы опять ненадолго вернемся к Expression Blend и покажем, как его можно использовать для создания анимации.
В графике трансформация определяет, как точки из одного координатного пространства отображаются в другом координатном пространстве. Обычно это описывается с помощью матрицы трансформации (transformation matrix),специальной
Трансформации реализуются через свойства трансформации. Существует несколько разных типов свойств трансформации, применяемых к разным типам объектов.
Так при использовании типа Brush трансформация определяется либо через свойство Brush.Transform (Трансформация кисти), если необходимо изменить содержимое кисти (например, если вы хотите повернуть изображение, прежде чем использовать его в ImageBrush ), либо с помощью свойства Brush.RelativeTransform (Относительная трансформация кисти), которое позволяет трансформировать кисть, используя относительные значения (это пригодиться при закрашивании одной кистью разных областей разных размеров).
Простые трансформации для типа выполняются с помощью свойства . Этот тип не поддерживает относительные трансформации.
Наконец, при использовании элемента пользовательского интерфейса (UI) трансформация задается через свойство RenderTransform. Например, трансформация эллипса будет выполняться с помощью свойства Ellipse.RenderTransform.
В следующем разделе будут рассмотрены разные типы трансформаций и показано использование этих свойств для конкретных типов объектов.
RotateTransform позволяет поворачивать элемент на заданный угол вокруг заданной центральной точки. Угол поворота задается свойством Angle (Угол) в градусах. Примем за начало отсчета (0 градусов) горизонтальный вектор, направленный вправо. Пусть вращение выполняется по часовой стрелке,тогда вертикальный вектор, указывающий вниз, является результатом поворота на 90 градусов.
Координаты центра трансформации задаются свойствами CenterX и CenterY. По умолчанию центр трансформации имеет координаты 0.0, таким образом, ось вращения по умолчанию находится в верхнем левом углу контейнера.
Рассмотрим пример XAML-кода, в котором выполняется вращение TextBlock с помощью RenderTrans-form, содержащего RotateTransform, который определяет поворот на 45 градусов:
<TextBlock Width="320" Height="40"
Text="This is the text to rotate" TextWrapping="Wrap">
<TextBlock.RenderTransform>
<RotateTransform Angle="45" />
</TextBlock.RenderTransform>
</TextBlock>
Как это выглядит, представлено на рис. 5.1.
(рис 5.1) Использование свойства RotateTransformКак видите, поворот этого текста был выполнен относительно центральной точки с координатами (0,0), т.е. верхнего левого угла.
В следующем XAML показано, как использовать CenterX и CenterY для выполнения вращения вокруг другой точки. В данном случае, поворот выполняется вокруг точки (100,200):
<TextBlock Width="320" Height="40"
Text="This is the text to rotate" TextWrapping="Wrap" >
<TextBlock.RenderTransform>
<RotateTransform Angle="45" CenterX="100" CenterY="200" />
</TextBlock.RenderTransform>
</TextBlock>
Результаты этой трансформации представлены на рис. 5.2.
(рис 5.2) Вращение вокруг другой центральной точки
ScaleTransform используется для изменения размера объекта в направлении по горизонтальной оси, вертикальной оси или в обоих направлениях.
При выполнении масштабирования объекта необходимо задать, по крайней мере, одну из осей масштабирования и то, на сколько должен быть изменен масштаб объекта по этой оси. Для масштабирования объекта по горизонтальной оси, оси х, используется свойство ScaleX, и для масштабирования по вертикальной оси, оси у, используется свойство ScaleY. Эти свойства принимают значения типа double, которые представляют, во сколько раз должен быть изменен объект в направлении по заданной оси. Следовательно, значения, больше 1, будут увеличивать объект. Например, если свойству ScaleX задать значение 2, это обеспечит увеличение размера объекта по горизонтали в два раза. Значения, меньше 1, но больше 0, будут обусловливать уменьшение объекта. Например, использование значения 0,5 приведет к уменьшению размера объекта вдвое в заданном направлении.
Итак, рассмотрим XAML-код, который обеспечивает создание красного прямоугольника шириной 96 пикселов и высотой 88 пикселов:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88"
Canvas.Left="112" Canvas.Top="72" />
На рис. 5.3 показано, как это выглядит в Silverlight.
(рис 5.3) Представление прямоугольника в SilverlightЧтобы применить к этому объекту ScaleTransform, используется RenderTransform и задается трансформация ScaleTransform. Вот соответствующий XAML:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88" Canvas.Left="112" Canvas.Top="72">
<Rectangle. RenderTransform="">
<ScaleTransform ScaleX="2" />
</Rectangle.RenderTransform >
</Rectangle>
На рис. 5.4 показано, как это выглядит в Silverlight.
(рис 5.4) Масштабирование с помощью ScaleTransformМожно заметить, что в результате применения ScaleTransform прямоугольник вытянулся вправо. Это произошло, потому что не был задан центр масштабирования. Для задания центра масштабирования используются свойства CenterX, для масштабировании по горизонтали, и CenterY, для масштабирования по вертикали. Эти свойства определяют координаты центра масштабирования. Эти координаты задаются относительно верхнего левого угла прямоугольника. Координата по умолчанию - 0, т.е. изменение размера будет происходить вправо и вниз.
Если свойству CenterX задать положительное значение (например, 50), масштабирование будет выполняться относительно точки X, смещенной на 50 пикселов вправо от левого края прямоугольника. В результате этого будет создаваться впечатление, что прямоугольник сместился на некоторое число пикселов (в зависимости от коэффициента масштабирования) относительно исходного положения. Это объясняется тем, что масштабирование выполняется относительно заданного центра, и левая часть прямоугольника увеличивается точно также, как и правая. Аналогичные результаты в вертикальном направлении можно получить, задавая ScaleY и CenterY. Рассмотрим пример:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="2" CenterX="50"/>
</Rectangle.RenderTransform>
</Rectangle>
Как в результате этого изменяется прямоугольник, можно увидеть на рис. рис. 5.5.
(рис 5.5) Масштабирование относительно центра масштабирования
Трансляция (translation) - это трансформация путем перемещения объекта на плоскости из одного места в другое. Описывается она путем задания векторов, которые определяют перемещение объекта относительно осей х и у. Для этого используются свойства X и Y. Чтобы передвинуть элемент на две единицы по горизонтали (объект будет двигаться вправо), свойству X задается значение 2. Чтобы переместить элемент влево, используется отрицательное значение, например, -2. Аналогично, для перемещения объекта по вертикали применяется свойство Y. Задание ему положительных значений обусловит перемещение объекта вниз по экрану, тогда как отрицательные значения обеспечат перемещение объекта вверх.
Рассмотрим пример трансформации трансляцией, которая обеспечивает перемещение уже знакомого нам красного прямоугольника вверх и влево через задание свойств X и Y. Эти значения образуют вектор,определяющий трансформацию.
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<TranslateTransform X="-50" Y="-50"/>
</Rectangle.RenderTransform>
</Rectangle>
Результаты этой трансформации представлены на рис. 5.6. Прямоугольник переместился вверх и влево относительно его исходного положения (рис. 5.3).
(рис 5.6) Использование свойства TranslateTransform
Наклон объекта подразумевает его поступательное пропорциональное изменение вдоль одной из осей. В результате квадрат или прямоугольник превращается в параллелограмм. Этот визуальный эффект очень полезен при создании впечатления трехмерного изображения на плоскости.
Можно задавать наклон под определенным углом вдоль оси х или у и относительно определенного центра. Конечно, все это можно комбинировать и наклонять объект относительно обеих осей одновременно.
Рассмотрим XAML-код, обеспечивающий наклон прямоугольника вдоль оси х на 45 градусов:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<SkewTransform AngleX="45"/>
</Rectangle.RenderTransform>
</Rectangle>
Результат представлен на рис. 5.7.
(рис 5.7) Наклонение прямоугольника с помощью SkewTransform
Наклон используется для создания эффекта трехмерного изображения. Ниже представлен пример XAML-кода, в котором используется три прямоугольника, два из которых наклонены по оси х, и один -по оси у, что создает впечатление трехмерного изображения:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="88" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<SkewTransform AngleX="45"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="88" Height="88" Canvas.Left="80" Canvas.Top="168">
<Rectangle.RenderTransform>
<SkewTransform AngleX="45"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="88" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<SkewTransform AngleY="45"/>
</Rectangle.RenderTransform>
</Rectangle>
Результаты этого представлены на рис. 5.8.
(рис 5.8) Имитация трехмерного изображения с помощью SkewTransform
Все трансформации по сути своей осуществляются путем совокупного изменения координатного пространства объекта с помощью
Математика матриц и реализация трансформаций выходят за рамки рассмотрения данного курса, но ради синтаксической полноты мы рассмотрим здесь, как их можно определять в Silverlight XAML.
Обратите внимание, что матрица, используемая в MatrixTransform, является аффинной.Это означает, что последний столбец матрицы всегда (0 0 1), и, таким образом, задаются только первые два столбца. Для этого используется свойство Matrix (Матрица), которое принимает строковое значение, образованное значениями первых двух столбцов, записанными через пробелы. Ниже приведен пример:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<MatrixTransform Matrix="1 0 1 2 0 1" />
</Rectangle.RenderTransform>
</Rectangle>
На рис. 5.9 продемонстрирован результат применения этой матрицы - растянутый и наклоненный прямоугольник.
(рис 5.9) Использование MatrixTransform
Как было представлено в предыдущем примере, с помощью аффинной матрицы и MatrixTransform можно создавать сложные трансформации. Однако не все хорошо разбираются в математике матриц. Поэтому применяется другая техника - сочетание трансформаций с помощью элемента Trans-formGroup (Группа трансформаций), который просто позволяет задавать несколько трансформаций. Объект подвергается комбинированному эффекту от всех трансформаций вместе взятых. Рассмотрим пример:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.2" ScaleY="1.2" />
<SkewTransform AngleX="30" />
<RotateTransform Angle="45" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
В этом примере комбинируются ScaleTransform, который обеспечивает увеличение размера фигуры вдоль обеих осей на 20%, наклон на 30 градусов по оси х и поворот на 45 градусов. Результаты этой трансформации представлены на рис. 5.10.
(рис 5.10) Сочетание трансформаций с помощью TransformGroup
Слово анимация буквально означает "оживить что-то". Таким образом, с помощью анимации вы можете вдохнуть жизнь в созданные вами объекты, меняя их атрибуты, такие как цвет, размер, прозрачность и другие свойства, во времени и в ответ на действия пользователя.
В XAML анимация элемента осуществляется за счет изменения одного или более его свойство во времени. Это время определяется с помощью временной шкалы. Например, чтобы элемент пересек экран за 5 секунд, необходимо было бы задать временную шкалу длительностью 5 секунд, которая обеспечила бы изменение свойства Canvas.Left от 0 до значения ширины экрана. В следующих разделах будут обсуждаться все доступные типы анимации и отличия анимации этих свойств с использованием ключевых кадров.
Прежде чем переходить к различным типа анимации, вы должны познакомиться с механизмами анимаций, которые включают Triggers (Триггеры), EventTriggers (Триггеры событий) и Storyboards (Раскадровки). Сначала рассмотрим эти концепции, а затем уже углубимся в различные типы анимации.
Анимации в Silverlight выполняются в ответ на некоторое событие, которое определяется с помощью триггера. В настоящее время Silverlight XAML поддерживает только один EventTrigger. Каждое свойство UI имеет коллекцию Triggers, которая используется для определения одного или более триггеров (т.е. одного или более EventTriggers ).
Итак, первый шаг в добавлении анимации в элемент - создание его коллекции триггеров. Затем в эту коллекцию необходимо будет добавить, по крайней мере, один триггер события. Например, первый шаг при анимации прямоугольника, определение коллекции триггеров, выглядит следующим образом:
<Rectangle x:Name="rect" Fill="Red"
Canvas.Top="100" Canvas.Left="100"
Width = "100" Height="100">
<Rectangle.Triggers>
</Rectangle.Triggers>
</Rectangle>
Далее необходимо определить EventTrigger, который будет добавлен в эту коллекцию. В данном EventTrigger с помощью свойства RoutedEvent (Отслеживаемое событие) задается событие, в ответ на возникновение которого будет запускаться анимация. В лекц. 6, "Элемент управления браузера Silverlight", подробно рассматриваются все события, поддерживаемые каждым из объектов в XAML, но обратите внимание, что RoutedEvent поддерживает только событие Loaded (Загружен).
Чтобы реализовать анимацию, которая будет запускаться после загрузки прямоугольника, EventTrigger необходимо описать следующим образом:
<EventTrigger RoutedEvent="Rectangle.Loaded"> </EventTrigger>
Вот фрагмент XAML-кода, запускающий эту анимацию:
<Rectangle x:Name="rect" Fill="Red" Canvas.Top="100"
Canvas.Left="100" Width = "100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Следующий шаг - создать анимацию, которая будет использоваться. Анимации размещаются в раскадровках,которым посвящен следующий раздел.
BeginStoryboard (Начать раскадровку) - это триггерное действие, содержащее объект . В объектах находятся описания анимации. При описании анимации эти объекты просто встраиваются в определение EventTrigger. Вот как это было бы выполнено для примера с прямоугольником, с которым мы работаем в этой лекции:
<Rectangle x:Name="rect" Fill="Red"
Canvas.Top="100" Canvas.Left="100" Width = "100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Теперь, когда среда анимации задана, можно приступать к описанию самой анимации. В основе анимации лежит изменение свойства во времени. Возможна анимация трех разных типов свойств:
Свойства типа double анимируются с помощью DoubleAnimation или DoubleAnimationUsingKeyFrames (Анимация свойств типа Double с использованием ключевых кадров). Этот метод используется для анимации свойств со значением типа double, например, таких размеров, как Canvas.Left, или таких Opacity.
Свойства типа точка анимируются с помощью PointAnimiation (Анимация точки) или PointAnimationUsingKeyFrames (Анимация точки с использованием ключевых кадров). Этот метод используется для анимации свойств со значениями, определенными как точка.Например, сегменты прямых или кривые описывают с помощью точек.
Свойства типа цвет анимируются с помощью ColorAnimation или ColorAnimationUsingKeyFrames (Цветовая анимация с использованием ключевых кадров). Этот метод используется для анимации свойств, содержащих значения цвета,например, фона или обводки элемента.
Анимация каждого из этих типов свойств выполняется от значения, заданного атрибутом From (От) (или его текущего значения, если этот атрибут не задан), до значения, заданного атрибутом To (До), или на значение, заданное атрибутом By (На).
Объект, к которому должна применяться анимация, задается свойством (Имя цели) данного типа анимации. В это свойство передается имя объекта, которое в описании объекта задано свойством x:Name (Имя). Кроме того, с помощью (Целевое свойство) задается анимируемое свойство. Заметьте, что составное или присоединенное свойство (такое как Canvas.Left ) заключается в круглые скобки. Итак, например, чтобы задать анимацию свойства типа Double для свойства Canvas.Left прямоугольника rect, необходимо написать следующий XAML:
<DoubleAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty=" (Canvas.Left)" />
Для определения времени перехода анимируемых свойств от одного значения к другому используется свойство Duration (Продолжительность). Оно определяется в формате ЧЧ:ММ:СС, где продолжительность 5 секунд записывается 00:00:05, или сокращенно - 0:0:5. Рассмотрим пример:
<DoubleAnimation Story="" board.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" />
Если вы не хотите, чтобы анимация начиналась сразу после загрузки, можно ввести задержку с помощью свойства BeginTime (Момент начала). Для него используется такой же синтаксис, как и для Duration.
<DoubleAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty=" (Canvas.Left)"
BeginTime="0:0:5" />
Можно настроить поведение анимации, умножая ее продолжительность на коэффициент скорости. Для этого используется свойство SpeedRatio (Коэффициент скорости). Например, в предыдущем случае была задана продолжительность 5 секунд. Задав SpeedRatio равным 2, можно изменить скорость воспроизведения, и анимация будет длиться 10 секунд. Или можно ускорить анимацию до 1 секунды, задавая SpeedRatio равным 0,2.
<DoubleAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)"
SpeedRatio="2" Duration="0:0:5" />
Анимация Silverlight обеспечивает возможность возвращения свойств, измененных в ходе анимации, к исходным значениям. Например, если значение типа double изменяется от 0 до 500 за определенный промежуток времени, свойство AutoReverse (Автоматическая перемотка) заставит анимацию выполниться в обратном направлении, от 500 к 0.
Обратите внимание, что если задана продолжительность анимации 5 секунд, и свойству AutoReverse задано значение true, продолжительность всей анимации будет 10 секунд. Далее представлен пример XAML со свойством AutoReverse:
<DoubleAnimation Storyboard.TargetName=" rect" Storyboard.TargetProperty=" (Canvas.Left)" AutoReverse="True" Duration="0:0:5" />
Существует ряд опций, посредством которых можно управлять поведением анимации по завершении ее выполнения. Задаются они с помощью свойства RepeatBehavior (Поведение повтора). Это свойство может принимать три типа значений:
Forever (Постоянно) определяет постоянное повторение.x. Например, если необходимо повторить анимацию три раза, задается значение 3x.Далее представлен полный XAML-код для анимации перемещения прямоугольника из точки 100 в точку 500 и назад в 100 по оси х с последующим троекратным повторением:
<Rectangle x:Name="rect" Fill="Red" Canvas.Top="100"
Canvas.Left="100" Width = "100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="3x" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)" To="500"
Duration ="0:0:5" AutoReverse="True" />
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Рассмотрим каждый из этих типов анимации немного более подробно. Сначала обратимся к атрибутам, необходимым для анимации каждого из типов, а затем перейдем к использованию анимации по ключевым кадрам.
Объект DoubleAnimation позволяет задавать, как значения типа double изменяется со временем. Анимация вычисляется как линейная интерполяция между значениями свойства в разные моменты времени.
При анимации свойств типа double задается значение в начале анимации, с помощью свойства From, и его абсолютное конечное значение, с помощью свойства To, или относительное конечное значение, посредством свойства By.
Например, чтобы изменить свойство Canvas.Left элемента от 100 (расположение рядом целевым краем экрана) до 500, можно задать свойству From значение 100 и 500 свойству To или 400 свойству By. Обратите внимание, что в случае задания обоих свойств, To имеет преимущество над By. Также если прямоугольник уже находится в определяемой From позиции, это свойство задавать не надо.
Предыдущий пример XAML-кода реализует это поведение. Прямоугольник располагается в позиции с Canvas.Left равным 100. DoubleAnimation определяет для To значение 500. Следовательно, анимация обеспечит изменение значения от 100 до 500, что обусловит перемещение прямоугольника по экрану вправо.
Поведение ColorAnimation очень близко поведению DoubleAnimation. Этот тип используется для изменения значения color элемента во времени. Анимация вычисляется как линейная интерполяция между значениями color в заданный промежуток времени.
При анимации цвета значение в начале анимации задается свойством From. Если это свойство не задано, за исходный принимается текущий цвет. Атрибут To определяет конечный цвет. Также можно задать атрибут By, тогда конечный цвет будет получен путем суммирования значения цвета, заданного в From (или исходного цвета), и цвета, заданного By.
Анимация цветовых свойств не означает анимацию содержимого свойства, потому что содержимым свойства обычно является кисть, а не цвет. Поэтому, например, если необходимо анимировать цвет заливки прямоугольника, целевым свойством анимации является не его свойство Fill, а свойство Color кисти SolidBrush, которая используется для выполнения заливки.
Далее представлен пример анимации цвета прямоугольника. Цвет меняется от черного к белому в течение 5 секунд:
<Rectangle x:Name="rect" Canvas.Top="100" Canvas.Left="100"
Width="100" Height="100" Fill="Black">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Как видите, в этом фрагменте XAML целевым свойством является свойство Color кисти SolidColorBrush, закрашивающей фигуру. Это типовой синтаксис XAML, используемый при работе с такими составными свойствами.
Для изменения во времени значения, определенного как точка, используется тип PointAnimation. Анимация вычисляется как линейная интерполяция между значениями в заданный промежуток времени.
Аналогично тому, как это делалось для анимации цвета и объектов типа Double, исходное значение задается с помощью свойства From и конечное значение задается как относительное (используя By ) или как абсолютное (используя To ). Далее представлен пример анимации конечной точки кривой Безье:
<Path Stroke="Black" >
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="100,100">
<QuadraticBezierSegment x:Name="seg"
Point1 = "200,0" Point2="300,100" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.TargetName="seg"
Storyboard.TargetProperty="Point2"
From="300,100" To="300,600" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Path.Triggers>
</Path>
В данном случае кривая Безье описывается начальной точкой (100,100), конечной точкой (300,100) и опорной точкой (200,0). Задано, что анимация запускается после загрузки контура и обеспечивает перемещение конечной точки кривой ( Point2 ) от точки (300,100) в точку (300,600) в течение 5 секунд.
Все рассматриваемые до сих пор типы анимации: Color Animation, DoubleAnimation и PointAnimation, -выполнялись путем изменения заданного свойства во времени с использованием линейной интерполяции. Например, при изменении значения типа double от 100 до 500 за 5 секунд, его приращение составляет 80 единиц в секунду.
Каждый из этих переходов может быть определен рядом промежуточных этапов, называемых ключевыми кадрами(key frames).Для изменения линейного поведения анимации от начального свойства к конечному используется один или более ключевых кадров. Затем задается, какой стиль анимации должен быть применен между различными точками.
Ключевые кадры определяются с помощью опорных моментов (key times).Это моменты, задаваемые относительно начала анимации и определяющие время окончания ключевого кадра. Итак, представим, что необходимо создать анимацию продолжительностью 9 секунд с тремя ключевыми кадрами, расположенными через равные промежутки времени друг от друга. Первый ключевой кадр можно задать в конце третьей секунды (0:0:3), второй - в конце шестой (0:0:6), и третий - в конце девятой (0:0:9). Вы не задаете продолжительность опорного момента, вы задаете время окончания каждого ключевого кадра.
В качестве еще одного примера возьмем анимацию объектов типа Double То есть для описания анимации объектов типа, с разделением промежутка 100 - 500 на две равные части. Анимация должна двигаться очень быстро первую половину пути и очень медленно вторую половину. Все перемещение должно занять 6 секунд. Поскольку средней точкой между 100 и 500 является 300, начало ключевого кадра определяем в точке 300. Указываем, что перемещение из начальной точкой в среднюю точку должно занять 1 секунду, используя опорный момент 0:0:1. Затем задаем продолжительность перемещения из средней точки в конечную точку равным 5 секундам, используя второй опорный момент, 0:0:6. Теперь элемент будет мгновенно перескакивать из начальной в среднюю точку и затем медленно проходить остальную часть пути.
В предыдущем примере оба сегмента анимации используют линейную интерполяцию. Для обеспечения дополнительной гибкости существует еще два типа ключевых кадров: ключевой кадр дискретной анимации, который мгновенно "перебрасывает" значение от одного значения к другому, и ключевой кадр сглаженной анимации, который обеспечивает плавное изменение значения, используя для определения интерполяции кривую второго порядка. (В следующих разделах будет рассмотрено описание анимации с использованием ключевых кадров для объектов типа Double. Аналогичные принципы применяются для анимации Point и Color.)
В наименованиях типов анимации с использованием ключевых кадров используется постфикс UsingKeyFrames (с использованием ключевых кадров). То есть для описания анимации объектов типа Double с ключевыми кадрами будет использоваться тип DoubleAnimationUsingKeyFrames, для которого будут заданы цель и свойство (точно также, как это делалось для DoubleAnimation). DoubleAnimationUsingKeyFrames включает описания ключевых кадров. (И как я уже говорил, то же самое касается PointAni-mationUsingKeyFrames и ColorAnimationUsingKeyFrames.)
Стандартным методом анимации изменения значений свойства является линейная интерполяция, при которой общая величина изменения равномерно распределяется по времени, отведенному на изменение. Другой способ - определение линейных шагов между кадрами с помощью LinearKeyFrame (Линейный ключевой кадр), в котором используется все та же линейная интерполяция, но между ключевыми кадрами, поэтому можно создавать эффекты ускорения/замедления.
Рассмотрим следующий пример анимации. В нем используется DoubleAnimationUsingKeyFrames. В этом случае определяются два ключевых кадра. Один кадр описывает линейную интерполяцию для изменения Canvas.Left от 0 до 300 за 1 секунду, второй - линейную интерполяцию для изменения Can- от 300 до 600 за 8 секунд. В результате создается эффект быстрого перемещения прямоугольника в первой половине пути и медленного движения во второй. Аналогичные принципы применяются для LinearPointKeyFrame и LinearColorKeyFrame.
<Rectangle Fill="#FFFF0000" Stroke="#FF000000"
Width="40" Height="40" Canvas.Top="40" x:Name="rect">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard >
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="300" />
<LinearDoubleKeyFrame KeyTime="0:0:9" Value="600" />
</DoubleAnimationUsingKeyFrames></Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers >
</Rectangle>
Если необходимо изменить свойство от одного значения к другому, но без применения линейной интерполяции, можно использовать ключевой кадр дискретной анимации. Он заставит объект "перескочить" на заданное значение в заданное время ключевого кадра. Далее показан тот же пример, что был представлен выше, но с использованием ключевого кадра дискретной анимации. За 1 секунду анимации прямоугольник перепрыгнет полпути на экране. Остальные 8 секунд анимации он будет проходить оставшийся отрезок пути.
<Rectangle Fill="#FFFF0000" Stroke="#FF000000"
Width="40" Height="40" Canvas.Top="40" x:Name="rect">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="rect"
Storyboard.TargetProperty=" (Canvas.Left)" >
<DiscreteDoubleKeyFrame KeyTime="0:0:1" Value="300" />
<DiscreteDoubleKeyFrame KeyTime="0:0:9" Value="600" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers >
</Rectangle>
Аналогичные принципы применяются для DiscretePointKeyFrame и DiscreteColorKeyFrame.
Для изменения свойства от одного значения к другому с использованием нелинейно изменяемого значения, обеспечивающим ускорение и замедление, применяется ключевой кадр сглаженной анимации. Для этого задается квадратическая кривая Безье. Тогда скорость изменения свойства от одного значения к другому определяется параллельной проекцией этой кривой.
Чтобы представить это, возьмем наглядный пример: солнце стоит прямо над головой, вы посылаете футбольный мяч в дальнюю часть поля. Проследите за тенью мяча. Пока он летит вверх, кажется, что тень движется с ускорением. Когда он достигает верхней точки, тень замедляет ход. Когда мяч начинает падать, скорость тени опять начинает возрастать до тех пор, пока мяч не упадет на землю.
Теперь представьте, что ваша анимация - это тень мяча, а плавная линия - это траектория мяча. Траектория, плавная линия или сплайн, описывается с помощью KeySpline (Опорная сглаженная линия). KeySpline определяет опорные точки квадратической кривой Безье. Кривая нормализована, так что первая точка кривой находится в 0, вторая - в 1. Для описания параболической дуги, именно по такой траектории падает мяч, KeySpline будет включать два нормализованных значения через запятую.
Описать кривую, по которой двигается мяч, можно с помощью сглаженной линии, используя KeySpline, например 0.3,0 0.6,1. Здесь задается первая (0.3,0) и вторая (0.6,1) точки кривой. В результате будет создан эффект быстрого ускорения анимации в первой трети пути, затем перемещение будет происходить с постоянной скоростью до прохождения примерно двух третей траектории мяча, и затем оставшуюся часть пути движение будет замедляться, имитируя падения мяча на землю.
Далее представлен пример использования KeySpline для описания сглаженной кривой при моделировании такого движения с помощью анимации DoubleAnimationUsingKeyFrames:
<Ellipse Fill= "#FF444444" Stroke="#FF444444"
Width = "40" Height="40" Canvas.Top="40" x:Name="ball">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ball"
Storyboard.TargetProperty=" (Canvas.Left)" >
<SplineDoubleKeyFrame KeyTime="0:0:5"
KeySpline="0.3,0 0.6,1" Value="600" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
В этом примере выполняется анимация эллипса. Его перемещение по экрану моделирует движение тени мяча, если смотреть на нее сверху.
Анимацию можно создавать графически в Expression Blend. Он формирует за вас XAML-код, применяя различные типы анимации автоматически.
В Blend для сайта, созданного для Silverlight 1, выберите в меню Window пункт Animation Workspace (Рабочая область анимации). При этом откроются инструменты для графического проектирования временных шкал. При редактировании свойств, которые должны меняться, используя визуальный редактор, будет формироваться XAML-код анимации. Это можно увидеть на рис. 5.11.
Внизу экрана представлена панель Objects And Timeline. В ней можно добавить временную шкалу и затем визуально вводить ключевые кадры. Чтобы добавить новую временную шкалу, щелкните кнопку + на панели Objects And Timeline (рис. 5.12).
(рис 5.11) Expression Blend в режиме Animation Workspace
(рис 5.12) Добавление новой временной шкалыЕсли щелкнуть кнопку +, откроется диалоговое окно, в котором будет предложено ввести имя создаваемой раскадровки. Диалог Create
(рис 5.13) Создание раскадровкиПри использовании Blend для сайта для Silverlight 1 анимацию можно создавать на уровне Canvas или как Resource (Ресурс). В первом случае анимации запускаются в ответ на триггеры, располагающиеся на холсте. Далее представлен пример XAML, созданного Blend из диалогового окна Create Resource:
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Timeline1"/>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
Обратите внимание, что если бы пользователь установил флажок Create As Resource (рис. 5.13), был бы создан в <Canvas.Resources>, и его пришлось бы запускать из JavaScript. В приложении для Silverlight 2 анимация сразу создается как ресурс. Более подробно остановимся на этом в лекц. 6.
Представление Objects And Timeline изменится, в нем будет отображена только что созданная временная шкала. Это можно увидеть на рис. 5.14.
(рис 5.14) Панель Objects And Timeline с новой временной шкалойНа рис. 5.14 вертикальная линия на нулевой отметке времени обозначает текущее время. (В Blend эта линия будет желтой.) Чтобы добавить ключевой кадр, просто перетащите эту линию на тот момент, куда необходимо вставить ключевой кадр, и щелкните кнопку Record Keyframe (Записать ключевой кадр). Эта кнопка находится сразу над временной шкалой слева от 0:00:000 на рис. 5.14.
Перетащите линию на 4-секундную отметку и добавьте ключевой кадр. Добавленный ключевой кадр будет отображаться как небольшой овал на временной шкале, как показано на рис. 5.15.
(рис 5.15) Добавление ключевого кадраУстановив временную шакалу на отметку 4 секунды и добавив ключевой кадр, можно перейти к редактированию цвета, местоположения, прозрачности или формы прямоугольника. Blend сам проведет соответствующие вычисления для облегчения создания анимации. В качестве примера на рис. 5.16 показан тот же прямоугольник, что мы видели на рис. 5.11, но с измененными заливкой и размерами.
(рис 5.16) Задание изменений в ключевом кадреВероятно, вы заметили, что если перемещать индикатор временной шкалы, можно предварительно просмотреть полученную анимацию и увидеть, как она выглядит в каждый отдельно взятый момент времени. На рис. 5.17 показано, как наш прямоугольник выглядит на второй секунде опорного времени. Для этого мы просто перетащили желтую вертикальную линию на отметку 2 секунды.
Ниже представлен полный XAML-код, сформированный Blend при создании анимации графическими средствами для сайта для Silverlight 1:
<Canvas xmlns=" http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="640" Height="480" Background = "White" x:Name="Page">
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard x:="" Name="Timeline1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="141"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[3].(TranslateTransform.Y)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="163"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="35.107"/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush. Color)" >
<SplineColorKeyFrame KeyTime="00:00:04" Value="#FF9D0B0B"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="1.7"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="1.549"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
<Rectangle Width="87" Height="69" Fill="Red" Stroke="#FF000000"
Canvas.Top="41" RenderTransformOrigin="0.5,0.5" x:Name="rect">
<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>
(рис 5.17) Предварительный просмотр анимацииВ данной лекции вы узнали, как в Silverlight XAML описываются трансформации и анимации. Были представлены различные типы трансформации, используемые для вращения, изменения размеров или наклонения объекта, а также произвольные трансформации с использованием аффинной матрицы. Затем были рассмотрены анимации и их запуск с помощью триггера XAML Показано, как анимация меняет значения свойств со временем, и представлены типы XAML, поддерживающие анимацию значений: double, point и color. Также мы научились использовать ключевые кадры для более тонкой настройки анимации. Наконец, вы познакомились со средством графического создания анимации, Expression Blend, и увидели, как просто в Blend создавать анимации визуально.
В лекц. 6 будет рассмотрен сам элемент управления Silverlight и более подробно описан полный набор его свойств, методов и событий.
В лекц. 4, "Основы XAML", вы научились с помощью XAML формировать визуальное представление графических элементов на экране, будь то векторная графика, растровые изображения (с помощью объекта Image ) или видео. В данной лекции будет рассмотрено, как улучшить представление этих графических элементов с помощью различных типов трансформаций (для изменения их вида) и анимации (для изменения атрибутов объекта во времени). Кроме того, будет представлена анимация по ключевым кадрам и описано их использование при создании более сложного поведения. В завершение мы опять ненадолго вернемся к Expression Blend и покажем, как его можно использовать для создания анимации.
В графике трансформация определяет, как точки из одного координатного пространства отображаются в другом координатном пространстве. Обычно это описывается с помощью матрицы трансформации (transformation matrix),специальной
Трансформации реализуются через свойства трансформации. Существует несколько разных типов свойств трансформации, применяемых к разным типам объектов.
Так при использовании типа Brush трансформация определяется либо через свойство Brush.Transform (Трансформация кисти), если необходимо изменить содержимое кисти (например, если вы хотите повернуть изображение, прежде чем использовать его в ImageBrush ), либо с помощью свойства Brush.RelativeTransform (Относительная трансформация кисти), которое позволяет трансформировать кисть, используя относительные значения (это пригодиться при закрашивании одной кистью разных областей разных размеров).
Простые трансформации для типа выполняются с помощью свойства . Этот тип не поддерживает относительные трансформации.
Наконец, при использовании элемента пользовательского интерфейса (UI) трансформация задается через свойство RenderTransform. Например, трансформация эллипса будет выполняться с помощью свойства Ellipse.RenderTransform.
В следующем разделе будут рассмотрены разные типы трансформаций и показано использование этих свойств для конкретных типов объектов.
RotateTransform позволяет поворачивать элемент на заданный угол вокруг заданной центральной точки. Угол поворота задается свойством Angle (Угол) в градусах. Примем за начало отсчета (0 градусов) горизонтальный вектор, направленный вправо. Пусть вращение выполняется по часовой стрелке,тогда вертикальный вектор, указывающий вниз, является результатом поворота на 90 градусов.
Координаты центра трансформации задаются свойствами CenterX и CenterY. По умолчанию центр трансформации имеет координаты 0.0, таким образом, ось вращения по умолчанию находится в верхнем левом углу контейнера.
Рассмотрим пример XAML-кода, в котором выполняется вращение TextBlock с помощью RenderTrans-form, содержащего RotateTransform, который определяет поворот на 45 градусов:
<TextBlock Width="320" Height="40"
Text="This is the text to rotate" TextWrapping="Wrap">
<TextBlock.RenderTransform>
<RotateTransform Angle="45" />
</TextBlock.RenderTransform>
</TextBlock>
Как это выглядит, представлено на рис. 5.1.
(рис 5.1) Использование свойства RotateTransformКак видите, поворот этого текста был выполнен относительно центральной точки с координатами (0,0), т.е. верхнего левого угла.
В следующем XAML показано, как использовать CenterX и CenterY для выполнения вращения вокруг другой точки. В данном случае, поворот выполняется вокруг точки (100,200):
<TextBlock Width="320" Height="40"
Text="This is the text to rotate" TextWrapping="Wrap" >
<TextBlock.RenderTransform>
<RotateTransform Angle="45" CenterX="100" CenterY="200" />
</TextBlock.RenderTransform>
</TextBlock>
Результаты этой трансформации представлены на рис. 5.2.
(рис 5.2) Вращение вокруг другой центральной точки
ScaleTransform используется для изменения размера объекта в направлении по горизонтальной оси, вертикальной оси или в обоих направлениях.
При выполнении масштабирования объекта необходимо задать, по крайней мере, одну из осей масштабирования и то, на сколько должен быть изменен масштаб объекта по этой оси. Для масштабирования объекта по горизонтальной оси, оси х, используется свойство ScaleX, и для масштабирования по вертикальной оси, оси у, используется свойство ScaleY. Эти свойства принимают значения типа double, которые представляют, во сколько раз должен быть изменен объект в направлении по заданной оси. Следовательно, значения, больше 1, будут увеличивать объект. Например, если свойству ScaleX задать значение 2, это обеспечит увеличение размера объекта по горизонтали в два раза. Значения, меньше 1, но больше 0, будут обусловливать уменьшение объекта. Например, использование значения 0,5 приведет к уменьшению размера объекта вдвое в заданном направлении.
Итак, рассмотрим XAML-код, который обеспечивает создание красного прямоугольника шириной 96 пикселов и высотой 88 пикселов:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88"
Canvas.Left="112" Canvas.Top="72" />
На рис. 5.3 показано, как это выглядит в Silverlight.
(рис 5.3) Представление прямоугольника в SilverlightЧтобы применить к этому объекту ScaleTransform, используется RenderTransform и задается трансформация ScaleTransform. Вот соответствующий XAML:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88" Canvas.Left="112" Canvas.Top="72">
<Rectangle. RenderTransform="">
<ScaleTransform ScaleX="2" />
</Rectangle.RenderTransform >
</Rectangle>
На рис. 5.4 показано, как это выглядит в Silverlight.
(рис 5.4) Масштабирование с помощью ScaleTransformМожно заметить, что в результате применения ScaleTransform прямоугольник вытянулся вправо. Это произошло, потому что не был задан центр масштабирования. Для задания центра масштабирования используются свойства CenterX, для масштабировании по горизонтали, и CenterY, для масштабирования по вертикали. Эти свойства определяют координаты центра масштабирования. Эти координаты задаются относительно верхнего левого угла прямоугольника. Координата по умолчанию - 0, т.е. изменение размера будет происходить вправо и вниз.
Если свойству CenterX задать положительное значение (например, 50), масштабирование будет выполняться относительно точки X, смещенной на 50 пикселов вправо от левого края прямоугольника. В результате этого будет создаваться впечатление, что прямоугольник сместился на некоторое число пикселов (в зависимости от коэффициента масштабирования) относительно исходного положения. Это объясняется тем, что масштабирование выполняется относительно заданного центра, и левая часть прямоугольника увеличивается точно также, как и правая. Аналогичные результаты в вертикальном направлении можно получить, задавая ScaleY и CenterY. Рассмотрим пример:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="2" CenterX="50"/>
</Rectangle.RenderTransform>
</Rectangle>
Как в результате этого изменяется прямоугольник, можно увидеть на рис. рис. 5.5.
(рис 5.5) Масштабирование относительно центра масштабирования
Трансляция (translation) - это трансформация путем перемещения объекта на плоскости из одного места в другое. Описывается она путем задания векторов, которые определяют перемещение объекта относительно осей х и у. Для этого используются свойства X и Y. Чтобы передвинуть элемент на две единицы по горизонтали (объект будет двигаться вправо), свойству X задается значение 2. Чтобы переместить элемент влево, используется отрицательное значение, например, -2. Аналогично, для перемещения объекта по вертикали применяется свойство Y. Задание ему положительных значений обусловит перемещение объекта вниз по экрану, тогда как отрицательные значения обеспечат перемещение объекта вверх.
Рассмотрим пример трансформации трансляцией, которая обеспечивает перемещение уже знакомого нам красного прямоугольника вверх и влево через задание свойств X и Y. Эти значения образуют вектор,определяющий трансформацию.
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<TranslateTransform X="-50" Y="-50"/>
</Rectangle.RenderTransform>
</Rectangle>
Результаты этой трансформации представлены на рис. 5.6. Прямоугольник переместился вверх и влево относительно его исходного положения (рис. 5.3).
(рис 5.6) Использование свойства TranslateTransform
Наклон объекта подразумевает его поступательное пропорциональное изменение вдоль одной из осей. В результате квадрат или прямоугольник превращается в параллелограмм. Этот визуальный эффект очень полезен при создании впечатления трехмерного изображения на плоскости.
Можно задавать наклон под определенным углом вдоль оси х или у и относительно определенного центра. Конечно, все это можно комбинировать и наклонять объект относительно обеих осей одновременно.
Рассмотрим XAML-код, обеспечивающий наклон прямоугольника вдоль оси х на 45 градусов:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<SkewTransform AngleX="45"/>
</Rectangle.RenderTransform>
</Rectangle>
Результат представлен на рис. 5.7.
(рис 5.7) Наклонение прямоугольника с помощью SkewTransform
Наклон используется для создания эффекта трехмерного изображения. Ниже представлен пример XAML-кода, в котором используется три прямоугольника, два из которых наклонены по оси х, и один -по оси у, что создает впечатление трехмерного изображения:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="88" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<SkewTransform AngleX="45"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="88" Height="88" Canvas.Left="80" Canvas.Top="168">
<Rectangle.RenderTransform>
<SkewTransform AngleX="45"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width="88" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<SkewTransform AngleY="45"/>
</Rectangle.RenderTransform>
</Rectangle>
Результаты этого представлены на рис. 5.8.
(рис 5.8) Имитация трехмерного изображения с помощью SkewTransform
Все трансформации по сути своей осуществляются путем совокупного изменения координатного пространства объекта с помощью
Математика матриц и реализация трансформаций выходят за рамки рассмотрения данного курса, но ради синтаксической полноты мы рассмотрим здесь, как их можно определять в Silverlight XAML.
Обратите внимание, что матрица, используемая в MatrixTransform, является аффинной.Это означает, что последний столбец матрицы всегда (0 0 1), и, таким образом, задаются только первые два столбца. Для этого используется свойство Matrix (Матрица), которое принимает строковое значение, образованное значениями первых двух столбцов, записанными через пробелы. Ниже приведен пример:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<MatrixTransform Matrix="1 0 1 2 0 1" />
</Rectangle.RenderTransform>
</Rectangle>
На рис. 5.9 продемонстрирован результат применения этой матрицы - растянутый и наклоненный прямоугольник.
(рис 5.9) Использование MatrixTransform
Как было представлено в предыдущем примере, с помощью аффинной матрицы и MatrixTransform можно создавать сложные трансформации. Однако не все хорошо разбираются в математике матриц. Поэтому применяется другая техника - сочетание трансформаций с помощью элемента Trans-formGroup (Группа трансформаций), который просто позволяет задавать несколько трансформаций. Объект подвергается комбинированному эффекту от всех трансформаций вместе взятых. Рассмотрим пример:
<Rectangle Fill="#FFFF0404" Stroke="#FF000000"
Width = "96" Height="88" Canvas.Left="80" Canvas.Top="80">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.2" ScaleY="1.2" />
<SkewTransform AngleX="30" />
<RotateTransform Angle="45" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
В этом примере комбинируются ScaleTransform, который обеспечивает увеличение размера фигуры вдоль обеих осей на 20%, наклон на 30 градусов по оси х и поворот на 45 градусов. Результаты этой трансформации представлены на рис. 5.10.
(рис 5.10) Сочетание трансформаций с помощью TransformGroup
Слово анимация буквально означает "оживить что-то". Таким образом, с помощью анимации вы можете вдохнуть жизнь в созданные вами объекты, меняя их атрибуты, такие как цвет, размер, прозрачность и другие свойства, во времени и в ответ на действия пользователя.
В XAML анимация элемента осуществляется за счет изменения одного или более его свойство во времени. Это время определяется с помощью временной шкалы. Например, чтобы элемент пересек экран за 5 секунд, необходимо было бы задать временную шкалу длительностью 5 секунд, которая обеспечила бы изменение свойства Canvas.Left от 0 до значения ширины экрана. В следующих разделах будут обсуждаться все доступные типы анимации и отличия анимации этих свойств с использованием ключевых кадров.
Прежде чем переходить к различным типа анимации, вы должны познакомиться с механизмами анимаций, которые включают Triggers (Триггеры), EventTriggers (Триггеры событий) и Storyboards (Раскадровки). Сначала рассмотрим эти концепции, а затем уже углубимся в различные типы анимации.
Анимации в Silverlight выполняются в ответ на некоторое событие, которое определяется с помощью триггера. В настоящее время Silverlight XAML поддерживает только один EventTrigger. Каждое свойство UI имеет коллекцию Triggers, которая используется для определения одного или более триггеров (т.е. одного или более EventTriggers ).
Итак, первый шаг в добавлении анимации в элемент - создание его коллекции триггеров. Затем в эту коллекцию необходимо будет добавить, по крайней мере, один триггер события. Например, первый шаг при анимации прямоугольника, определение коллекции триггеров, выглядит следующим образом:
<Rectangle x:Name="rect" Fill="Red"
Canvas.Top="100" Canvas.Left="100"
Width = "100" Height="100">
<Rectangle.Triggers>
</Rectangle.Triggers>
</Rectangle>
Далее необходимо определить EventTrigger, который будет добавлен в эту коллекцию. В данном EventTrigger с помощью свойства RoutedEvent (Отслеживаемое событие) задается событие, в ответ на возникновение которого будет запускаться анимация. В лекц. 6, "Элемент управления браузера Silverlight", подробно рассматриваются все события, поддерживаемые каждым из объектов в XAML, но обратите внимание, что RoutedEvent поддерживает только событие Loaded (Загружен).
Чтобы реализовать анимацию, которая будет запускаться после загрузки прямоугольника, EventTrigger необходимо описать следующим образом:
<EventTrigger RoutedEvent="Rectangle.Loaded"> </EventTrigger>
Вот фрагмент XAML-кода, запускающий эту анимацию:
<Rectangle x:Name="rect" Fill="Red" Canvas.Top="100"
Canvas.Left="100" Width = "100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Следующий шаг - создать анимацию, которая будет использоваться. Анимации размещаются в раскадровках,которым посвящен следующий раздел.
BeginStoryboard (Начать раскадровку) - это триггерное действие, содержащее объект . В объектах находятся описания анимации. При описании анимации эти объекты просто встраиваются в определение EventTrigger. Вот как это было бы выполнено для примера с прямоугольником, с которым мы работаем в этой лекции:
<Rectangle x:Name="rect" Fill="Red"
Canvas.Top="100" Canvas.Left="100" Width = "100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Теперь, когда среда анимации задана, можно приступать к описанию самой анимации. В основе анимации лежит изменение свойства во времени. Возможна анимация трех разных типов свойств:
Свойства типа double анимируются с помощью DoubleAnimation или DoubleAnimationUsingKeyFrames (Анимация свойств типа Double с использованием ключевых кадров). Этот метод используется для анимации свойств со значением типа double, например, таких размеров, как Canvas.Left, или таких Opacity.
Свойства типа точка анимируются с помощью PointAnimiation (Анимация точки) или PointAnimationUsingKeyFrames (Анимация точки с использованием ключевых кадров). Этот метод используется для анимации свойств со значениями, определенными как точка.Например, сегменты прямых или кривые описывают с помощью точек.
Свойства типа цвет анимируются с помощью ColorAnimation или ColorAnimationUsingKeyFrames (Цветовая анимация с использованием ключевых кадров). Этот метод используется для анимации свойств, содержащих значения цвета,например, фона или обводки элемента.
Анимация каждого из этих типов свойств выполняется от значения, заданного атрибутом From (От) (или его текущего значения, если этот атрибут не задан), до значения, заданного атрибутом To (До), или на значение, заданное атрибутом By (На).
Объект, к которому должна применяться анимация, задается свойством (Имя цели) данного типа анимации. В это свойство передается имя объекта, которое в описании объекта задано свойством x:Name (Имя). Кроме того, с помощью (Целевое свойство) задается анимируемое свойство. Заметьте, что составное или присоединенное свойство (такое как Canvas.Left ) заключается в круглые скобки. Итак, например, чтобы задать анимацию свойства типа Double для свойства Canvas.Left прямоугольника rect, необходимо написать следующий XAML:
<DoubleAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty=" (Canvas.Left)" />
Для определения времени перехода анимируемых свойств от одного значения к другому используется свойство Duration (Продолжительность). Оно определяется в формате ЧЧ:ММ:СС, где продолжительность 5 секунд записывается 00:00:05, или сокращенно - 0:0:5. Рассмотрим пример:
<DoubleAnimation Story="" board.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" />
Если вы не хотите, чтобы анимация начиналась сразу после загрузки, можно ввести задержку с помощью свойства BeginTime (Момент начала). Для него используется такой же синтаксис, как и для Duration.
<DoubleAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty=" (Canvas.Left)"
BeginTime="0:0:5" />
Можно настроить поведение анимации, умножая ее продолжительность на коэффициент скорости. Для этого используется свойство SpeedRatio (Коэффициент скорости). Например, в предыдущем случае была задана продолжительность 5 секунд. Задав SpeedRatio равным 2, можно изменить скорость воспроизведения, и анимация будет длиться 10 секунд. Или можно ускорить анимацию до 1 секунды, задавая SpeedRatio равным 0,2.
<DoubleAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)"
SpeedRatio="2" Duration="0:0:5" />
Анимация Silverlight обеспечивает возможность возвращения свойств, измененных в ходе анимации, к исходным значениям. Например, если значение типа double изменяется от 0 до 500 за определенный промежуток времени, свойство AutoReverse (Автоматическая перемотка) заставит анимацию выполниться в обратном направлении, от 500 к 0.
Обратите внимание, что если задана продолжительность анимации 5 секунд, и свойству AutoReverse задано значение true, продолжительность всей анимации будет 10 секунд. Далее представлен пример XAML со свойством AutoReverse:
<DoubleAnimation Storyboard.TargetName=" rect" Storyboard.TargetProperty=" (Canvas.Left)" AutoReverse="True" Duration="0:0:5" />
Существует ряд опций, посредством которых можно управлять поведением анимации по завершении ее выполнения. Задаются они с помощью свойства RepeatBehavior (Поведение повтора). Это свойство может принимать три типа значений:
Forever (Постоянно) определяет постоянное повторение.x. Например, если необходимо повторить анимацию три раза, задается значение 3x.Далее представлен полный XAML-код для анимации перемещения прямоугольника из точки 100 в точку 500 и назад в 100 по оси х с последующим троекратным повторением:
<Rectangle x:Name="rect" Fill="Red" Canvas.Top="100"
Canvas.Left="100" Width = "100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="3x" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)" To="500"
Duration ="0:0:5" AutoReverse="True" />
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Рассмотрим каждый из этих типов анимации немного более подробно. Сначала обратимся к атрибутам, необходимым для анимации каждого из типов, а затем перейдем к использованию анимации по ключевым кадрам.
Объект DoubleAnimation позволяет задавать, как значения типа double изменяется со временем. Анимация вычисляется как линейная интерполяция между значениями свойства в разные моменты времени.
При анимации свойств типа double задается значение в начале анимации, с помощью свойства From, и его абсолютное конечное значение, с помощью свойства To, или относительное конечное значение, посредством свойства By.
Например, чтобы изменить свойство Canvas.Left элемента от 100 (расположение рядом целевым краем экрана) до 500, можно задать свойству From значение 100 и 500 свойству To или 400 свойству By. Обратите внимание, что в случае задания обоих свойств, To имеет преимущество над By. Также если прямоугольник уже находится в определяемой From позиции, это свойство задавать не надо.
Предыдущий пример XAML-кода реализует это поведение. Прямоугольник располагается в позиции с Canvas.Left равным 100. DoubleAnimation определяет для To значение 500. Следовательно, анимация обеспечит изменение значения от 100 до 500, что обусловит перемещение прямоугольника по экрану вправо.
Поведение ColorAnimation очень близко поведению DoubleAnimation. Этот тип используется для изменения значения color элемента во времени. Анимация вычисляется как линейная интерполяция между значениями color в заданный промежуток времени.
При анимации цвета значение в начале анимации задается свойством From. Если это свойство не задано, за исходный принимается текущий цвет. Атрибут To определяет конечный цвет. Также можно задать атрибут By, тогда конечный цвет будет получен путем суммирования значения цвета, заданного в From (или исходного цвета), и цвета, заданного By.
Анимация цветовых свойств не означает анимацию содержимого свойства, потому что содержимым свойства обычно является кисть, а не цвет. Поэтому, например, если необходимо анимировать цвет заливки прямоугольника, целевым свойством анимации является не его свойство Fill, а свойство Color кисти SolidBrush, которая используется для выполнения заливки.
Далее представлен пример анимации цвета прямоугольника. Цвет меняется от черного к белому в течение 5 секунд:
<Rectangle x:Name="rect" Canvas.Top="100" Canvas.Left="100"
Width="100" Height="100" Fill="Black">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Как видите, в этом фрагменте XAML целевым свойством является свойство Color кисти SolidColorBrush, закрашивающей фигуру. Это типовой синтаксис XAML, используемый при работе с такими составными свойствами.
Для изменения во времени значения, определенного как точка, используется тип PointAnimation. Анимация вычисляется как линейная интерполяция между значениями в заданный промежуток времени.
Аналогично тому, как это делалось для анимации цвета и объектов типа Double, исходное значение задается с помощью свойства From и конечное значение задается как относительное (используя By ) или как абсолютное (используя To ). Далее представлен пример анимации конечной точки кривой Безье:
<Path Stroke="Black" >
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="100,100">
<QuadraticBezierSegment x:Name="seg"
Point1 = "200,0" Point2="300,100" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.TargetName="seg"
Storyboard.TargetProperty="Point2"
From="300,100" To="300,600" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Path.Triggers>
</Path>
В данном случае кривая Безье описывается начальной точкой (100,100), конечной точкой (300,100) и опорной точкой (200,0). Задано, что анимация запускается после загрузки контура и обеспечивает перемещение конечной точки кривой ( Point2 ) от точки (300,100) в точку (300,600) в течение 5 секунд.
Все рассматриваемые до сих пор типы анимации: Color Animation, DoubleAnimation и PointAnimation, -выполнялись путем изменения заданного свойства во времени с использованием линейной интерполяции. Например, при изменении значения типа double от 100 до 500 за 5 секунд, его приращение составляет 80 единиц в секунду.
Каждый из этих переходов может быть определен рядом промежуточных этапов, называемых ключевыми кадрами(key frames).Для изменения линейного поведения анимации от начального свойства к конечному используется один или более ключевых кадров. Затем задается, какой стиль анимации должен быть применен между различными точками.
Ключевые кадры определяются с помощью опорных моментов (key times).Это моменты, задаваемые относительно начала анимации и определяющие время окончания ключевого кадра. Итак, представим, что необходимо создать анимацию продолжительностью 9 секунд с тремя ключевыми кадрами, расположенными через равные промежутки времени друг от друга. Первый ключевой кадр можно задать в конце третьей секунды (0:0:3), второй - в конце шестой (0:0:6), и третий - в конце девятой (0:0:9). Вы не задаете продолжительность опорного момента, вы задаете время окончания каждого ключевого кадра.
В качестве еще одного примера возьмем анимацию объектов типа Double То есть для описания анимации объектов типа, с разделением промежутка 100 - 500 на две равные части. Анимация должна двигаться очень быстро первую половину пути и очень медленно вторую половину. Все перемещение должно занять 6 секунд. Поскольку средней точкой между 100 и 500 является 300, начало ключевого кадра определяем в точке 300. Указываем, что перемещение из начальной точкой в среднюю точку должно занять 1 секунду, используя опорный момент 0:0:1. Затем задаем продолжительность перемещения из средней точки в конечную точку равным 5 секундам, используя второй опорный момент, 0:0:6. Теперь элемент будет мгновенно перескакивать из начальной в среднюю точку и затем медленно проходить остальную часть пути.
В предыдущем примере оба сегмента анимации используют линейную интерполяцию. Для обеспечения дополнительной гибкости существует еще два типа ключевых кадров: ключевой кадр дискретной анимации, который мгновенно "перебрасывает" значение от одного значения к другому, и ключевой кадр сглаженной анимации, который обеспечивает плавное изменение значения, используя для определения интерполяции кривую второго порядка. (В следующих разделах будет рассмотрено описание анимации с использованием ключевых кадров для объектов типа Double. Аналогичные принципы применяются для анимации Point и Color.)
В наименованиях типов анимации с использованием ключевых кадров используется постфикс UsingKeyFrames (с использованием ключевых кадров). То есть для описания анимации объектов типа Double с ключевыми кадрами будет использоваться тип DoubleAnimationUsingKeyFrames, для которого будут заданы цель и свойство (точно также, как это делалось для DoubleAnimation). DoubleAnimationUsingKeyFrames включает описания ключевых кадров. (И как я уже говорил, то же самое касается PointAni-mationUsingKeyFrames и ColorAnimationUsingKeyFrames.)
Стандартным методом анимации изменения значений свойства является линейная интерполяция, при которой общая величина изменения равномерно распределяется по времени, отведенному на изменение. Другой способ - определение линейных шагов между кадрами с помощью LinearKeyFrame (Линейный ключевой кадр), в котором используется все та же линейная интерполяция, но между ключевыми кадрами, поэтому можно создавать эффекты ускорения/замедления.
Рассмотрим следующий пример анимации. В нем используется DoubleAnimationUsingKeyFrames. В этом случае определяются два ключевых кадра. Один кадр описывает линейную интерполяцию для изменения Canvas.Left от 0 до 300 за 1 секунду, второй - линейную интерполяцию для изменения Can- от 300 до 600 за 8 секунд. В результате создается эффект быстрого перемещения прямоугольника в первой половине пути и медленного движения во второй. Аналогичные принципы применяются для LinearPointKeyFrame и LinearColorKeyFrame.
<Rectangle Fill="#FFFF0000" Stroke="#FF000000"
Width="40" Height="40" Canvas.Top="40" x:Name="rect">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard >
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Canvas.Left)" >
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="300" />
<LinearDoubleKeyFrame KeyTime="0:0:9" Value="600" />
</DoubleAnimationUsingKeyFrames></Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers >
</Rectangle>
Если необходимо изменить свойство от одного значения к другому, но без применения линейной интерполяции, можно использовать ключевой кадр дискретной анимации. Он заставит объект "перескочить" на заданное значение в заданное время ключевого кадра. Далее показан тот же пример, что был представлен выше, но с использованием ключевого кадра дискретной анимации. За 1 секунду анимации прямоугольник перепрыгнет полпути на экране. Остальные 8 секунд анимации он будет проходить оставшийся отрезок пути.
<Rectangle Fill="#FFFF0000" Stroke="#FF000000"
Width="40" Height="40" Canvas.Top="40" x:Name="rect">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="rect"
Storyboard.TargetProperty=" (Canvas.Left)" >
<DiscreteDoubleKeyFrame KeyTime="0:0:1" Value="300" />
<DiscreteDoubleKeyFrame KeyTime="0:0:9" Value="600" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Rectangle.Triggers >
</Rectangle>
Аналогичные принципы применяются для DiscretePointKeyFrame и DiscreteColorKeyFrame.
Для изменения свойства от одного значения к другому с использованием нелинейно изменяемого значения, обеспечивающим ускорение и замедление, применяется ключевой кадр сглаженной анимации. Для этого задается квадратическая кривая Безье. Тогда скорость изменения свойства от одного значения к другому определяется параллельной проекцией этой кривой.
Чтобы представить это, возьмем наглядный пример: солнце стоит прямо над головой, вы посылаете футбольный мяч в дальнюю часть поля. Проследите за тенью мяча. Пока он летит вверх, кажется, что тень движется с ускорением. Когда он достигает верхней точки, тень замедляет ход. Когда мяч начинает падать, скорость тени опять начинает возрастать до тех пор, пока мяч не упадет на землю.
Теперь представьте, что ваша анимация - это тень мяча, а плавная линия - это траектория мяча. Траектория, плавная линия или сплайн, описывается с помощью KeySpline (Опорная сглаженная линия). KeySpline определяет опорные точки квадратической кривой Безье. Кривая нормализована, так что первая точка кривой находится в 0, вторая - в 1. Для описания параболической дуги, именно по такой траектории падает мяч, KeySpline будет включать два нормализованных значения через запятую.
Описать кривую, по которой двигается мяч, можно с помощью сглаженной линии, используя KeySpline, например 0.3,0 0.6,1. Здесь задается первая (0.3,0) и вторая (0.6,1) точки кривой. В результате будет создан эффект быстрого ускорения анимации в первой трети пути, затем перемещение будет происходить с постоянной скоростью до прохождения примерно двух третей траектории мяча, и затем оставшуюся часть пути движение будет замедляться, имитируя падения мяча на землю.
Далее представлен пример использования KeySpline для описания сглаженной кривой при моделировании такого движения с помощью анимации DoubleAnimationUsingKeyFrames:
<Ellipse Fill= "#FF444444" Stroke="#FF444444"
Width = "40" Height="40" Canvas.Top="40" x:Name="ball">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ball"
Storyboard.TargetProperty=" (Canvas.Left)" >
<SplineDoubleKeyFrame KeyTime="0:0:5"
KeySpline="0.3,0 0.6,1" Value="600" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard >
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
В этом примере выполняется анимация эллипса. Его перемещение по экрану моделирует движение тени мяча, если смотреть на нее сверху.
Анимацию можно создавать графически в Expression Blend. Он формирует за вас XAML-код, применяя различные типы анимации автоматически.
В Blend для сайта, созданного для Silverlight 1, выберите в меню Window пункт Animation Workspace (Рабочая область анимации). При этом откроются инструменты для графического проектирования временных шкал. При редактировании свойств, которые должны меняться, используя визуальный редактор, будет формироваться XAML-код анимации. Это можно увидеть на рис. 5.11.
Внизу экрана представлена панель Objects And Timeline. В ней можно добавить временную шкалу и затем визуально вводить ключевые кадры. Чтобы добавить новую временную шкалу, щелкните кнопку + на панели Objects And Timeline (рис. 5.12).
(рис 5.11) Expression Blend в режиме Animation Workspace
(рис 5.12) Добавление новой временной шкалыЕсли щелкнуть кнопку +, откроется диалоговое окно, в котором будет предложено ввести имя создаваемой раскадровки. Диалог Create
(рис 5.13) Создание раскадровкиПри использовании Blend для сайта для Silverlight 1 анимацию можно создавать на уровне Canvas или как Resource (Ресурс). В первом случае анимации запускаются в ответ на триггеры, располагающиеся на холсте. Далее представлен пример XAML, созданного Blend из диалогового окна Create Resource:
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard x:Name="Timeline1"/>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
Обратите внимание, что если бы пользователь установил флажок Create As Resource (рис. 5.13), был бы создан в <Canvas.Resources>, и его пришлось бы запускать из JavaScript. В приложении для Silverlight 2 анимация сразу создается как ресурс. Более подробно остановимся на этом в лекц. 6.
Представление Objects And Timeline изменится, в нем будет отображена только что созданная временная шкала. Это можно увидеть на рис. 5.14.
(рис 5.14) Панель Objects And Timeline с новой временной шкалойНа рис. 5.14 вертикальная линия на нулевой отметке времени обозначает текущее время. (В Blend эта линия будет желтой.) Чтобы добавить ключевой кадр, просто перетащите эту линию на тот момент, куда необходимо вставить ключевой кадр, и щелкните кнопку Record Keyframe (Записать ключевой кадр). Эта кнопка находится сразу над временной шкалой слева от 0:00:000 на рис. 5.14.
Перетащите линию на 4-секундную отметку и добавьте ключевой кадр. Добавленный ключевой кадр будет отображаться как небольшой овал на временной шкале, как показано на рис. 5.15.
(рис 5.15) Добавление ключевого кадраУстановив временную шакалу на отметку 4 секунды и добавив ключевой кадр, можно перейти к редактированию цвета, местоположения, прозрачности или формы прямоугольника. Blend сам проведет соответствующие вычисления для облегчения создания анимации. В качестве примера на рис. 5.16 показан тот же прямоугольник, что мы видели на рис. 5.11, но с измененными заливкой и размерами.
(рис 5.16) Задание изменений в ключевом кадреВероятно, вы заметили, что если перемещать индикатор временной шкалы, можно предварительно просмотреть полученную анимацию и увидеть, как она выглядит в каждый отдельно взятый момент времени. На рис. 5.17 показано, как наш прямоугольник выглядит на второй секунде опорного времени. Для этого мы просто перетащили желтую вертикальную линию на отметку 2 секунды.
Ниже представлен полный XAML-код, сформированный Blend при создании анимации графическими средствами для сайта для Silverlight 1:
<Canvas xmlns=" http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="640" Height="480" Background = "White" x:Name="Page">
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard x:="" Name="Timeline1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="141"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[3].(TranslateTransform.Y)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="163"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="35.107"/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush. Color)" >
<SplineColorKeyFrame KeyTime="00:00:04" Value="#FF9D0B0B"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="1.7"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="1.549"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
<Rectangle Width="87" Height="69" Fill="Red" Stroke="#FF000000"
Canvas.Top="41" RenderTransformOrigin="0.5,0.5" x:Name="rect">
<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>
(рис 5.17) Предварительный просмотр анимацииВ данной лекции вы узнали, как в Silverlight XAML описываются трансформации и анимации. Были представлены различные типы трансформации, используемые для вращения, изменения размеров или наклонения объекта, а также произвольные трансформации с использованием аффинной матрицы. Затем были рассмотрены анимации и их запуск с помощью триггера XAML Показано, как анимация меняет значения свойств со временем, и представлены типы XAML, поддерживающие анимацию значений: double, point и color. Также мы научились использовать ключевые кадры для более тонкой настройки анимации. Наконец, вы познакомились со средством графического создания анимации, Expression Blend, и увидели, как просто в Blend создавать анимации визуально.
В лекц. 6 будет рассмотрен сам элемент управления Silverlight и более подробно описан полный набор его свойств, методов и событий.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.