Заполнение анимированного круга с помощью синусоиды

Я пытаюсь оживить круг, чтобы он заполнялся синусоидой. Вот пример изображения, которое я сделал:

Пример изображения

Таким образом, черный - это круг, и, как вы можете видеть, он отрезан синусоидально. Можете ли вы сделать это, пока синусоида "путешествует" в горизонтальном направлении и решает, где волна должна быть размещена, по значению Y окружностей на всю высоту? (чтобы это выглядело так, будто в круге есть вода, создающая волны сверху и способная решить, сколько "воды" находится в круге)

Есть ли способ сделать это? Может быть, есть место, где можно прочитать об этих видах анимации?

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

1 ответ

Решение

Основная функция, позволяющая сделать что-то подобное, - OpacityMask. В приведенном ниже примере используется VisualBrush, установленный в Tile для маски, и свойство transform кисти, чтобы выполнить движение, которое вы описали.

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="WpfApplication1.MainWindow"
        Title="MainWindow" Height="447" Width="569">
    <Window.Resources>
        <Storyboard x:Key="Wave">
            <DoubleAnimation Storyboard.TargetProperty="(UIElement.OpacityMask).(Brush.RelativeTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="ellipse" RepeatBehavior="Forever" From="0" To="1" Duration="0:0:1" />
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource Wave}"/>
        </EventTrigger>
    </Window.Triggers>
    <Canvas>
        <Ellipse x:Name="ellipse" Fill="#FF82C6FF" Height="160" Canvas.Left="320" Canvas.Top="80" Width="160">
            <Ellipse.OpacityMask>
                <VisualBrush Visual="{Binding ElementName=wave}" TileMode="Tile" Viewport="0,-1,1,3" Stretch="None"  >
                    <VisualBrush.RelativeTransform>
                        <TransformGroup>
                            <ScaleTransform />
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform Y="{Binding Value,ElementName=y}"  />
                        </TransformGroup>
                    </VisualBrush.RelativeTransform>
                </VisualBrush>
            </Ellipse.OpacityMask>

            </Ellipse>
        <Grid x:Name="wave" Height="377" Canvas.Left="80" Canvas.Top="23" Width="160" Background="#00000000">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="{Binding Value,ElementName=amplitude}"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>
            <Path Fill="#FF82C6FF" Data="M12.5,1.6925709 C31.25,1.6925709 31.25,18.615654 50,18.615654 68.75,18.615654 68.75,1.6925709 87.5,1.6925709 87.499909,27.077196 87.5,27.077107 87.5,27.077107 63.28125,27.077136 12.5,27.077196 12.5,27.077196 12.5,27.077196 12.500094,27.077196 12.5,1.6925709 z" Stretch="Fill" Grid.Row="1"/>
            <Rectangle Fill="#FF82C6FF" Grid.Row="2" Margin="0,-1,0,0" />
        </Grid>
        <Slider x:Name="y" Width="200" Minimum="-0.6" Maximum="1" Value="0"/>
        <Slider x:Name="amplitude" Width="200" Minimum="1" Maximum="100" Value="20" Canvas.Top="23"/>
    </Canvas>
</Window>

Чтобы скрыть маску, вы можете поместить ее непосредственно в VisualBrush вместо привязки, как описано выше. Возможно, вы также захотите взглянуть на другие типы кистей и их преобразования, а также на область просмотра / окно просмотра.

Обновление: маска теперь состоит из двух частей, поэтому амплитуду волны можно регулировать отдельно. Вы также можете настроить ScaleTransform.ScaleX чтобы изменить частоту, но вам нужно убедиться, что вы получаете всю волну или анимацию заикания, например, попробуйте 0.5,0.25,0.1

Другие вопросы по тегам