Анимация свойств Double в WinRT
102WinRT --- Анимация свойств Double
Класс DoubleAnimation, который мы использовали в предыдущей статье, позволяет применить анимацию к любому свойству типа double, поддерживаемому свойством зависимости, например Width и/или Height:
<Page
x:Class="WinRTTestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinRTTestApp">
<Page.Resources>
<Storyboard x:Key="storyboard"
AutoReverse="True"
RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="Height"
EnableDependentAnimation="True"
From="500" To="100" Duration="0:0:1" />
<DoubleAnimation Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="Width"
EnableDependentAnimation="True"
From="100" To="500" Duration="0:0:1" />
</Storyboard>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Name="ellipse">
<Ellipse.Fill>
<LinearGradientBrush>
<GradientStop Offset="0" Color="LightBlue" />
<GradientStop Offset="1" Color="Lime" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</Page>
Две анимации выполняются параллельно. Первая изменяет свойство Width элемента Ellipse от 100 до 600, а вторая - свойство Height элемента Ellipse от 600 до 100. Два размера лишь на миг встречаются в средней точке, образуя круг. Настройки AutoReverse и RepeatBehavior могут задаваться либо для Storyboard (как сделано у меня), либо для отдельных анимаций.
Анимация запускается при загрузке страницы и работает «бесконечно»:
public MainPage()
{
this.InitializeComponent();
Loaded += (sender, args) =>
{
(this.Resources["storyboard"] as Storyboard).Begin();
};
}
Так как кисть LinearGradientBrush, которой заполняется Ellipse, использует градиент по умолчанию - от левого верхнего угла к правому нижнему, градиент в действительности слегка сдвигается во время анимации.
Width и Height - не единственные свойства Ellipse, к которым может применяться анимация. Свойство StrokeThickness, определяемое классом Shape, также относится к типу double и поддерживается свойством зависимости. Следующий фрагмент выводит эллипс, контур которого обозначается серией точек, а анимация изменяет толщину пунктирной линии:
<Page ...>
<Page.Resources>
<Storyboard x:Key="storyboard">
<DoubleAnimation Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="StrokeThickness"
EnableDependentAnimation="True"
From="1" To="80" Duration="0:0:3"
RepeatBehavior="Forever"
AutoReverse="True" />
</Storyboard>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Name="ellipse"
Stroke="LimeGreen"
StrokeDashCap="Round"
StrokeDashArray="0 2" />
</Grid>
</Page>
Анимация запускается в событии Loaded тем же кодом, что и в предыдущей программе.
Значение «0 2» свойства StrokeDashArray означает, что пунктирная линия состоит из отрезка, имеющего длину 0 единиц, за которым следует пробел величиной в 2 единицы (где единицей является значение StrokeThickness). Отрезок имеет закругленные концы благодаря свойству StrokeDashCap, причем закругление увеличивает длину отрезка, так что отрезок фактически превращается в точку с диаметром, равным StrokeThickness. Центры точек разделяются интервалом, равным двойной величине StrokeThickness, так что контуры точек разделяются интервалом StrokeThickness.
В этой анимации количество точек уменьшается, а затем возрастает с увеличением и уменьшением значения StrokeThickness в ходе анимации. Точки словно исчезают и появляются в правой части эллипса:
Нет ли у Ellipse других свойств типа double? Как насчет свойства StrokeDashOffset, которое указывает, с какой позиции начинаются отрезки и интервалы в пунктирной линии? Следующая разметка XAML использует объект Path с кривыми Безье для рисования знака бесконечности пунктирной линией. Анимация применяется к свойству StrokeDashOffset, чтобы точки «перемещались» по фигуре:
<Page ...>
<Page.Resources>
<Storyboard x:Key="storyboard">
<DoubleAnimation Storyboard.TargetName="path"
Storyboard.TargetProperty="StrokeDashOffset"
EnableDependentAnimation="True"
From="0" To="1.5" Duration="0:0:1"
RepeatBehavior="Forever" />
</Storyboard>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Viewbox>
<Path Name="path"
Margin="12"
Stroke="LimeGreen"
StrokeThickness="24"
StrokeDashArray="0 1.5"
StrokeDashCap="Round"
Data="M 100 0
C 45 0, 0 45, 0 100
S 45 200, 100 200
S 200 150, 250 100
S 345 0, 400 0
S 500 45, 500 100
S 455 200, 400 200
S 300 150, 250 100
S 155 0, 100 0" />
</Viewbox>
</Grid>
</Page>
К сожалению, я не могу изобразить точки, ползающие по «восьмерке», на странице сайта, чтобы передать эффект анимации:
Определение Path в этой программе использует хорошо известную аппроксимацию Безье для четверти круга. Для круга с центром в точке (0,9) дуга правой нижней четверти круга начинается в точке (100,0) и заканчивается в точке (0,100). Она очень хорошо аппроксимируется кривой Безье, которая также начинается в точке (100,0) и заканчивается в точке (0,100), с двумя контрольными точками (100,55) и (55,100). Из четырех дуг «Безье 55» можно составить целый круг.
Таким образом, дуга четверти круга, которая начинает знак бесконечности в левом верхнем углу, начинается в точке (100,0) и заканчивается в точке (0,100), но центр находится в точке (100,100) вместо (0,0), поэтому первая контрольная точка смещена на 55 единиц влево от (100,0), а вторая на 55 единиц вверх от (0,100) - получаем (45,0) и (0, 45).
Следующая кривая Безье продолжает фигуру в левом нижнем углу, начиная с точки (0, 100) (конца предыдущей кривой) и заканчивая в точке (100, 200) с контрольными точками (0,155) и (45,200). Но оставшаяся часть разметки продолжается не фигурами с маркером «C» (обозначающим кубическую кривую Безье - Cubic), а фигурами с маркером «S» (обозначающим плавную кривую Безье - Smooth). Как известно, две кривые Безье соединяются плавно, если их общая точка и две смежные контрольные точки коллинеарны (то есть находятся на одной прямой).
Присутствие фигуры S в синтаксисе разметки Path приводит к тому, что первая контрольная точка вычисляется автоматически так, чтобы она была коллинеарна с начальной точкой и предыдущей контрольной точкой и находилась от начальной точки на одинаковом расстоянии с предыдущей коллинеарной точкой. Таким образом, для первой кривой Безье с точками (0, 45) и (0,100) первая контрольная точка первой фигуры S имеет координаты (0,155).
При рисовании пунктирной линии, конец которой соединяется с началом, очень высока вероятность того, что отрезок в начальной точке будет неполным. Значение StrokeThickness, равное 24, было вычислено экспериментально, и оно не обязано быть целым числом. Например, в версии этой программы для Windows Phone я остановился на значении StrokeThickness 23,98.
Изучая остальные классы библиотеки Shapes в поиске свойств типа double, подходящих для анимации, вы также найдете свойства X1, Y1, X2 и Y2 класса Line. Позднее я покажу, как организовать анимацию свойств типа Point, встречающихся во многих классах, производных от PathSegment.
Современные веб-приложения уже давно запускаются и просматриваются не только с десктопных компьютеров, а также с различных мобильных устройств. Доля рынка мобильной рекламы в интернете растет с каждым годом, поэтому для мониторинга мобильной рекламы на ваших сайтах, понадобится гибкий сервис, наподобие admobispy.com, предлагающий многофункциональную систему отчетов по подробной информации о объявлениях в различных сетях.