Масштабирование элементов в WinRT

75

Класс 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, при котором элемент отражается относительно горизонтальной оси:

Прозрачное отражение картинки

Позже я продемонстрирую другой способ добиться желаемого эффекта на уровне работы с пикселами растрового изображения и соответствующего задания прозрачности.

Пройди тесты
Лучший чат для C# программистов