WPF动画StrokeDashArray

jav*_*irs 2 wpf animation

我正在尝试在WPF中创建一个动画,但我对于放置所有内容的地方感到很困惑.我需要一个像自己画画一样的圆圈.

要做到这一点,我有一个设计精美的圆圈(下面有一个带有模糊的描边圆圈的一个描边圆圈)然后我有另一个带有StrokeDashArray的圆圈.我计划将这个圆圈用作第一个的opacityMask,并为StrokeDashArray设置动画以显示circ.

我一直在玩,我可以修改从[0,100]到[50 100]的StrokeDashArray,我得到一条覆盖圆圈的增长线(我真的不明白0 100和50 100来自哪里..只是试过,直到看起来不错.

所以现在我的问题是在哪里分发这些东西.

我的代码到目前为止看起来像:

<UserControl bla bla bla bla>
    <!-- The mask that should be animated -- >
    <Ellipse Name="Mask" Stroke="White"StrokeThickness="13" StrokeDashArray="10 100"/>
    <!-- StrokeDashArray should be animated from "0 100" to "50 100"  -->

    <!-- The Blurry shadow of the line -->
    <Ellipse Name="blurry" Stroke="#FF7CA2CE" StrokeThickness="5">
        <Ellipse.Effect>
            <BlurEffect/>
        </Ellipse.Effect>
        <Ellipse.OpacityMask>
            <VisualBrush Visual="{Binding ElementName=Mask}"/>
        </Ellipse.OpacityMask>
    </Ellipse>

    <!-- The line itself -->
    <Ellipse Name="core" Stroke="Blue" StrokeThickness="1">
        <Ellipse.OpacityMask>
            <VisualBrush Visual="{Binding ElementName=Mask}"/>
        </Ellipse.OpacityMask>
    </Ellipse>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

所以现在我需要在StrokeDashArray中的第一个元素上执行动画并从后面的代码中启动它(C#)我也可以将动画作为资源放在其中并从代码中启动它,或者在代码中执行整个动画,我不在乎,但请具体说明在哪里添加代码..我感到迷茫.

我还尝试将模糊和核心线添加到一个网格,然后将VisualBrush应用到它(所以我只应用它一次,而不是两次)但效果更加丑陋,因为模糊的线条被剪切而且不像我们那样轻柔地结束希望它是呵呵呵

Sooo,任何帮助?!?!?!?!?!

sa_*_*213 6

这是一个有点一个棘手的作为StrokeDashArray是一个DoubleCollection,所以你不能真正动画值内,有它在UI反映.

一种选择是为double属性设置动画并创建一个DoubleCollection绑定到的属性StrokeDashArray.

这是一个工作示例:

XAML:

<Window x:Class="WpfApplication21.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="211.75" Width="213" Name="UI">

    <Grid DataContext="{Binding ElementName=UI}">

        <Ellipse x:Name="lo" Stroke="White" StrokeThickness="13" StrokeDashArray="{Binding StrokeArray}" />

        <Ellipse Name="blurry" Stroke="#FF7CA2CE" StrokeThickness="5">
            <Ellipse.Effect>
                <BlurEffect/>
            </Ellipse.Effect>
            <Ellipse.OpacityMask>
                <VisualBrush Visual="{Binding ElementName=lo}"/>
            </Ellipse.OpacityMask>
        </Ellipse>

        <!-- The line itself -->
        <Ellipse Name="core" Stroke="Blue" StrokeThickness="1">
            <Ellipse.OpacityMask>
                <VisualBrush Visual="{Binding ElementName=lo}"/>
            </Ellipse.OpacityMask>
        </Ellipse>

        <Button Content="Start" HorizontalAlignment="Left" Height="49" Margin="29,65,0,0" VerticalAlignment="Top" Width="150" Click="Button_Click_1"/>

    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

码:

namespace WpfApplication21
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public double StrokeValue
        {
            get { return (double)GetValue(StrokeValueProperty); }
            set { SetValue(StrokeValueProperty, value); }
        }

        public static readonly DependencyProperty StrokeValueProperty =
            DependencyProperty.Register("StrokeValue", typeof(double), typeof(MainWindow)
            , new PropertyMetadata(0.0, new PropertyChangedCallback(OnStrokeValueChanged)));

        private static void OnStrokeValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as MainWindow).StrokeArray = new DoubleCollection { (double)e.NewValue, 100 };
        }


        public DoubleCollection StrokeArray
        {
            get { return (DoubleCollection)GetValue(StrokeArrayProperty); }
            set { SetValue(StrokeArrayProperty, value); }
        }

        public static readonly DependencyProperty StrokeArrayProperty =
            DependencyProperty.Register("StrokeArray", typeof(DoubleCollection), typeof(MainWindow)
            , new PropertyMetadata(new DoubleCollection { 0, 100 }));


    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        var storyboard = new Storyboard();
        var animation = new DoubleAnimation(0,50,new Duration(TimeSpan.FromSeconds(5)));
        storyboard.Children.Add(animation);
        Storyboard.SetTarget(animation, this);
        Storyboard.SetTargetProperty(animation,new PropertyPath( MainWindow.StrokeValueProperty));
        storyboard.Begin();
    }

    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

实际上,您可以为StrokeDashOffset设置动画,而不是尝试为StrokeDashArray设置动画.

<Rectangle
   Width="70"
   Height="70"
   StrokeDashArray="2 0 0 2"
   StrokeThickness="2"
   Stroke="Black"
   Opacity="1"
   Fill="Transparent">
   <Rectangle.Triggers> 
            <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
                <BeginStoryboard> 
                    <Storyboard> 
                        <DoubleAnimation 
                           To="20" 
                           Duration="0:0:5" 
                           RepeatBehavior="Forever" 
                           By="2" 
                           Storyboard.TargetProperty="StrokeDashOffset" /> 
                    </Storyboard> 
                </BeginStoryboard> 
            </EventTrigger> 
        </Rectangle.Triggers> 
   </Rectangle>
Run Code Online (Sandbox Code Playgroud)