Анимированные кисти

77

Анимированные кисти — еще одна распространенная техника в анимации WPF, которую реализовать столь же легко, как анимированные трансформации. Опять-таки, этот прием заключается в проникновении в определенное подсвойство, которое нужно изменить, используя для этого анимацию соответствующего типа.

Ниже показан пример, в котором изменяется кисть RadialGradientBrush. При запуске анимации центральная часть радиального градиента движется по эллиптической траектории, создавая некий трехмерный эффект. В то же время внешний цвет градиента изменяется.

Для реализации этой анимации понадобятся анимации двух типов, которые пока еще не рассматривались. ColorAnimation обеспечивает плавный переход между двумя цветами, создавая тонкий эффект сдвига цвета. PointAnimation позволяет перемещать точку из одного места в другое (по сути, это то же самое, что и одновременная модификация обеих координат X и Y с использованием отдельной анимации DoubleAnimation с линейной интерполяцией). Анимацию PointAnimation можно применять для деформации фигуры, состоящей из точек, или же изменять местоположение центра радиального градиента, как в данном примере.

Ниже показан код разметки:

<Grid>
                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                    <RowDefinition Height="auto"></RowDefinition>
                </Grid.RowDefinitions>
                <Ellipse Name="ellipse" Stretch="Uniform" Margin="5">
                    <Ellipse.Fill>
                        <RadialGradientBrush GradientOrigin="0.7,0.3" RadiusX="0.6" RadiusY="0.6">
                            <GradientStop Color="White" Offset="0"></GradientStop>
                            <GradientStop Color="Orange" Offset="1"></GradientStop>
                        </RadialGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <Button Content="StartAnimation" Grid.Row="1" Width="100" Padding="5"
                        Margin="5">
                    <Button.Triggers>
                        <EventTrigger RoutedEvent="Button.Click">
                            <EventTrigger.Actions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <PointAnimation Storyboard.TargetName="ellipse"
                                                        Storyboard.TargetProperty="Fill.GradientOrigin"
                                                        From="0.7,0.3" To="0.3,0.7" Duration="0:0:6"
                                                        AutoReverse="True" RepeatBehavior="Forever"></PointAnimation>
                                        <ColorAnimation Storyboard.TargetName="ellipse"
                                                        Storyboard.TargetProperty="Fill.GradientStops[1].Color"
                                                        To="LimeGreen" Duration="0:0:6" AutoReverse="True"
                                                        RepeatBehavior="Forever"></ColorAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger.Actions>
                        </EventTrigger>
                    </Button.Triggers>
                </Button>
 </Grid>
Изменение радиального градиента

Варьируя цвета и смещения в LinearGradientBrush и RadialGradientBrush, можно создать огромное разнообразие завораживающих эффектов. Вдобавок градиентные кисти также имеют собственное свойство RelativeTransform, которое можно использовать для вращения, масштабирования, растяжения и наклона. Команда разработчиков WPF располагает забавным инструментом Gradient Obsession, который предназначен для построения анимации на основе градиентов.

Кисть VisualBrush

Как уже известно, кисть VisualBrush позволяет захватить внешний вид любого элемента и использовать его для заполнения другой поверхности. Этой другой поверхностью может быть что угодно — от обычного прямоугольника до букв текста.

Ниже показан базовый пример. Сверху находится реальная кнопка. Ниже используется кисть VisualBrush для заполнения прямоугольника изображением этой кнопки, которая растягивается и вращается, создавая эффект разнообразных трансформаций.

VisualBrush также открывает некоторые интересные возможности для анимации. Например, вместо анимации реального элемента можно выполнить анимацию простого прямоугольника, имеющего то же заполнение.

Воспроизвести этот эффект с помощью VisualBrush очень легко. Для начала потребуется создать другой элемент, который заполняет себя с использованием VisualBrush. Эта кисть VisualBrush должна нарисовать себя на основе внешнего вида элемента, который будет анимироваться (в данном примере элементом является именованная рамка).

Чтобы поместить прямоугольник в позицию исходного элемента, их обоих можно вставить в одну и ту же ячейку Grid. Размер ячеек устанавливается равным размеру исходного элемента (рамки), а прямоугольник растягивается до его размеров. Другой выбор добавить перекрывающий контейнер Canvas поверх реального контейнера компоновки. (Затем можно привязать свойства анимации к свойствам ActualWidth и ActualHeight реального элемента, лежащего в основе, чтобы гарантировать их совпадение.)

После добавления прямоугольника понадобится просто подстроить анимации, чтобы анимировать его трансформации. Финальный шаг — по окончании анимации скрыть прямоугольник. Ниже показан код для реализации данного примера:

<Grid>
      <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
      </Grid.RowDefinitions>

      <Button Name="visual" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button.Content>Test</Button.Content>
        <Button.Triggers>
          <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
              <Storyboard  RepeatBehavior="Forever">
                <DoubleAnimation Storyboard.TargetName="rectangle"
                                 Storyboard.TargetProperty="RenderTransform.Children[0].AngleY"
                                 To="180" Duration="0:0:15" AutoReverse="True"></DoubleAnimation>
                <DoubleAnimation Storyboard.TargetName="rectangle"
                                 Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
                                 To="180" Duration="0:0:20" AutoReverse="True"></DoubleAnimation>
                <DoubleAnimation Storyboard.TargetName="rectangle"
                                 Storyboard.TargetProperty="Opacity"
                                 To="0.1" Duration="0:0:4" AutoReverse="True"></DoubleAnimation>
              </Storyboard>
            </BeginStoryboard>
          </EventTrigger>
        </Button.Triggers>
      </Button>
      
      <Rectangle Grid.Row="1" Name="rectangle" Width="100" Stretch="Uniform" ClipToBounds="False" RenderTransformOrigin="0.5,0.5">
        <Rectangle.Fill>
          <VisualBrush Visual="{Binding ElementName=visual}">
           
          </VisualBrush>
        </Rectangle.Fill>
        <Rectangle.RenderTransform>
          
            <TransformGroup>
              <SkewTransform CenterX="0.5"></SkewTransform>
              <RotateTransform CenterX="0.5" CenterY="0.5"></RotateTransform>
            </TransformGroup>
          
        </Rectangle.RenderTransform>
      </Rectangle>
    </Grid>
Анимация VisualBrush
Пройди тесты
Лучший чат для C# программистов