Преобразования в WinRT

65

В предыдущих статьях было показано, как использовать анимации для перемещения объектов по экрану, изменения их размеров, цвета или прозрачности и даже перемещать точки по контуру фигуры. Но некоторые виды анимации остались без внимания. Допустим, вы хотите, чтобы кнопка поворачивалась при щелчке? Не то чтобы вертеться как пропеллер, а просто качнуться туда-сюда, словно говоря: «Не могу сдержать свой энтузиазм предвкушая выполнение вашей команды».

Для таких (и других аналогичных) ситуаций существуют преобразования (transforms). Когда-то они назывались графическими преобразованиями, и даже (вероятно чтобы отпугнуть непосвященных) матричными преобразованиями. Но в последние годы преобразования освободились из рабства у специалистов по компьютерной графике и стали доступными всем программистам.

Я не хочу сказать, что преобразования теперь не связаны с математикой (да, математика будет). Просто теперь можно использовать преобразования в Windows Runtime, не разбираясь в математических формулах, заложенных в основу их работы.

Краткий обзор преобразований

Преобразование представляет собой математическую формулу, применяемую к точке (x, y) для создания новой точки (x',y'). Применяя одну формулу ко всем точкам визуального объекта, можно переместить его, перевернуть и даже внести в него различные деформации. Подобные преобразования используются в дизайне всех современных приложений, например таких, как программа для освоения языков программирования pascal abc для новичков, расширяя классические пользовательские интерфейсы, добавляя к ним красивую интерактивность.

Преобразования поддерживаются в Windows Runtime тремя свойствами, определяемыми UIElement: RenderTransform, RenderTransformOrigin и Projection. Так как эти свойства определяются классом UIElement, преобразования не ограничиваются векторной графикой, как когда-то. Они могут применяться к любому элементу, включая Image, TextBlock и Button. Если применить преобразование к классу, производному от Panel (например, к Grid), оно также применится ко всем потомкам этой панели.

Для применения преобразований к элементам используется синтаксис элементов свойств - как в следующем примере, в котором свойству RenderTransform задается экземпляр класса, производного от Transform (в данном случае RotateTransform):

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Image Source="http://professorweb.ru/my/windows8/rt/level1/files/win8logo.png"
               VerticalAlignment="Bottom"
               HorizontalAlignment="Center"
               Stretch="Uniform" Width="400">
            <Image.RenderTransform>
                <RotateTransform Angle="315" />
            </Image.RenderTransform>
        </Image>
</Grid>

Свойство Angle класса RotateTransform задает поворот на 315° по часовой стрелке:

Поворот изображения

Но результат выглядит нормально только потому, что я знал, что изображение будет поворачиваться относительно левого верхнего угла, поэтому намеренно расположил элемент Image снизу страницы. Поворот в двух измерениях всегда происходит относительно конкретной точки (как если бы вы поворачивали фотографию, прикрепленную кнопкой к стене), и правильный выбор этой точки является непростым аспектом работы с преобразованиями.

Свойству RenderTransform можно задать объект любого из семи классов, производных от Transform:

Object
    DependencyObject 
        GeneralTransform 
            Transform
                CompositeTransform
                MatrixTransform
                TranslateTransform
                ScaleTransform
                SkewTransform
                RotateTransform
                TransformGroup

Эти классы определяют традиционные двумерные аффинные преобразования. Термин «аффинный» означает, что преобразованный объект сохраняет определенное сходство с исходным: прямая линия всегда переходит в другую прямую. Она может изменить положение, размер или ориентацию, но остается прямой. Линии, параллельные до аффинного преобразования, остаются параллельными после него.

Windows Runtime также поддерживает разновидность неаффинных преобразований, часто используемых в трехмерной перспективе. Windows Runtime можно использовать для достижения трехмерных эффектов; для этого свойству Project определяемому классом UIElement, задается экземпляр одного из двух классов производных от Projection:

Object
    DependencyObject
        Projection
            Matrix3DProjection
            PlaneProjection

Поворот в пространстве всегда осуществляется по некоторой оси. Поворот по оси Y (вертикальной) продемонстрирован в следующем примере:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Image Source="http://professorweb.ru/my/windows8/rt/level1/files/win8logo.png"
               VerticalAlignment="Center"
               HorizontalAlignment="Center"
               Width="900">
            <Image.Projection>
                <PlaneProjection RotationY="-50"></PlaneProjection>
            </Image.Projection>
        </Image>
</Grid>

При таком повороте к плоскости экрана словно добавляется третье измерение:

Поворот изображения в трехмерном пространстве

Очевидно, параллельность линий при таких преобразованиях не сохраняется. Именно поэтому объект выглядит так, словно он находится в трехмерном пространстве.

Преобразования Projection иногда называются «псевдотрехмерными» и используются для добавления иллюзии объема в Windows Runtime. Анимацию можно определить так, чтобы элемент «распахивался» наподобие двери или переворачивался как игральная карта, но сам элемент при этом остается плоским. Собственно, отсюда и взялось слово «плоскость» (plane) в имени одного из классов Projection - фактически вы берете плоский элемент и проецируете его в трехмерное пространство.

Программисты с хорошей математической подготовкой смогут заставить класс Matrix3DProjection отображать реальные трехмерные объекты в Windows Runtime. Однако в Windows Runtime отсутствуют некоторые важные возможности трехмерной графики - например, затенение поверхностей с учетом расположения источников света или отсечение объектов, частично скрытых другими объектами. Если вам потребуется реализовать в своем приложении Windows 8 полноценную трехмерную графику, используйте технологию Direct3D, которая доступна только из кода C++.

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