Масштабирование элементов в WinRT
75WinRT --- Масштабирование элементов
Класс ScaleTransform определяет свойства ScaleX и ScaleY, которые независимо увеличивают или уменьшают размер элемента в горизонтальном и вертикальном направлениях. Чтобы сохранить исходные пропорции целевого объекта, используйте одинаковые значения ScaleX и ScaleY. Если это анимация, вам потребуются два объекта анимации. Преобразование ScaleTransform не влияет на свойства ActualWidth и ActualHeight элемента.
Эффект масштабирования используется во всех современных приложениях для создания графических анимаций и насыщенного дизайна. Многие бесплатные программы на besplatnyeprogrammy.net, такие как Firefox, ThunderBird, Skype и другие, применяют этот эффект для улучшения юзабилити пользовательского интерфейса программы, обеспечивая тем самым высокую релевантность для пользователей.
Вы уже видели, как использовать Viewbox для растяжения элемента TextBlock с нарушением исходных пропорций. А вот как это делается при помощи ScaleTransform:
<Page ...>
<Page.Resources>
<Style TargetType="TextBlock">
<Setter Property="RenderTransformOrigin" Value="0.5 0.5" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Page.Resources>
<Grid Background="#222">
<TextBlock Text="Масштабирование текста"
FontSize="92">
<TextBlock.RenderTransform>
<ScaleTransform x:Name="transformScale" />
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
<Page.Triggers>
<EventTrigger>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="ScaleX"
Storyboard.TargetName="transformScale"
AutoReverse="True"
BeginTime="0:0:1"
From="1" To="0.01" Duration="0:0:1"
RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="ScaleY"
Storyboard.TargetName="transformScale"
AutoReverse="True"
From="10" To="0.1" Duration="0:0:1"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Page.Triggers>
</Page>
Впрочем, сначала я писал эту программу немного иначе. Изначально объекту TextBlock задавалось свойство FontSize, равное 1, после чего посредством анимации свойство ScaleX изменялось от 1 до 96, а свойство ScaleY - от 96 до 1, с выполнением в обратном направлении и бесконечным повторением. Вероятно, это решение сработало бы, но в итоге шрифт высотой 1 пиксел увеличивался в размерах в 96 раз, вместо того чтобы превращаться в шрифт высотой 96 пикселей. Чтобы программа работала так, как я хотел, я задал объекту TextBlock шрифт с размером 96 пикселей и запустил анимацию со смещением. Объект TextBlock поочередно «растягивается» по горизонтали и вертикали:
Масштабирование, как и поворот, всегда выполняется относительно центральной точки. Класс ScaleTransform, как и RotateTransform, определяет свойства CenterX и CenterY; также можно задать значение RenderTransformOrigin, как я сделал в предыдущей программе. Центром масштабирования является точка, которая не меняет своего положения после выполнения масштабирования.
Центры масштабирования и вращения играют важную роль в манипуляциях с экранными объектами (например, фотографиями) с использованием пальцев. В процессе увеличения, уменьшения и поворота фотографии центры масштабирования и вращения изменяются при относительных перемещениях пальцев.
Отрицательные коэффициенты масштабирования «отражают» элемент относительно горизонтальной или вертикальной оси. Этот прием особенно полезен для создания эффектов отражения. К сожалению, в Windows Runtime отсутствует важный аспект этого эффекта: свойство UIElement с именем OpacityMask типа Brush, позволяющее определить шкалу прозрачности по значениям альфа-канала цветов градиентной кисти. В Windows Runtime эффект постепенного растворения приходится имитировать, накрывая элемент другим элементом с градиентной кистью, использующей прозрачность, и фоновым цветом.
Данная возможность продемонстрирована в следующем примере. Верхнюю половину панели Grid занимают два объекта: Image и другая панель Grid. Вторая панель Grid содержит тот же объект Image, накрытый объектом Rectangle с кистью LinearGradientBrush, которая постепенно растворяется от фонового цвета наверху до прозрачности внизу:
<Page ...>
<Grid Background="#FF2D2D2D">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Image HorizontalAlignment="Center"
Source="http://professorweb.ru/my/windows8/rt/level5/files/img19482.jpg" />
<Grid HorizontalAlignment="Center" RenderTransformOrigin="0 1">
<Grid.RenderTransform>
<ScaleTransform ScaleY="-0.6" />
</Grid.RenderTransform>
<Image Source="http://professorweb.ru/my/windows8/rt/level5/files/img19482.jpg"/>
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0 0" StartPoint="0 1">
<GradientStop Offset="1" Color="#FF1D1D1D" />
<GradientStop Offset="0" Color="Transparent" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Grid>
</Page>
Внутренняя панель Grid также отражается относительно своего нижнего края. Свойство RenderTransformOrigin устанавливает центр преобразования в левом нижнем углу, а у ScaleTransform свойству ScaleY задается значение -1, при котором элемент отражается относительно горизонтальной оси:
Позже я продемонстрирую другой способ добиться желаемого эффекта на уровне работы с пикселами растрового изображения и соответствующего задания прозрачности.