15- Animation

1,Animation类:

DoubleAnimation widthAnimation = new DoubleAnimation();
            widthAnimation.To = this.Width - 30;
            widthAnimation.Duration = TimeSpan.FromSeconds(5);
            widthAnimation.Completed += animation_Completed;

            DoubleAnimation heightAnimation = new DoubleAnimation();
            heightAnimation.To = (this.Height - 50)/3;
            heightAnimation.Duration = TimeSpan.FromSeconds(5);

            cmdGrow.BeginAnimation(Button.WidthProperty, widthAnimation);
            cmdGrow.BeginAnimation(Button.HeightProperty, heightAnimation);
        }

   创建类,并且设定其两个值.---注意,动画类的最后的值并不会还原.

           --------当忽略From时,将从当前值到To值

           -----------当忽略了to时,将从当前值到依赖性的期待值.


            DoubleAnimation widthAnimation = new DoubleAnimation();
            widthAnimation.Duration = TimeSpan.FromSeconds(5);
            DoubleAnimation heightAnimation = new DoubleAnimation();
            heightAnimation.Duration = TimeSpan.FromSeconds(5);

            cmdGrow.BeginAnimation(Button.WidthProperty, widthAnimation);
            cmdGrow.BeginAnimation(Button.HeightProperty, heightAnimation);

           -------------By...定义增大量.

 DoubleAnimation widthAnimation = new DoubleAnimation();
            widthAnimation.By = 10;
            widthAnimation.Duration = TimeSpan.FromSeconds(0.5);

            cmdGrowIncrementally.BeginAnimation(Button.WidthProperty, widthAnimation);

  Duration---对象:设定动画动作间隔

Duration可以和TimeSpan进行转换.并且设定了两个值

Duration.Automatic---持续1秒
Duration.Forever---永远不动

   如何还原对象之前的值:

image


AutoReverse属性=true的动画,在执行到指定值之后会继续进行反向动画直到还原.

FillBehavior=Stop,在执行完动画后自动返回.

Duration=Duration.Forever则不执行动画.

使用 如下方法可以删除动画.

cmdGrow.BeginAnimation(Button.WidthProperty, null);

二 ,TimeLine抽象类的属性:

image


image

RepeatBehavior:

1,通过次数重复动画: new RepeatBehavior(2)

2,通过事件重复动画:new RepeatBehavior(5)--重复2次半

3,设定IsCumulative;表明在重复的时候,是否从当前动画值开始.

4,不断重复动画.RepeatBehavior.Forever.


三,故事板------在XAML中创建动画

1,创建故事板对象

image

2,创建触发器

image


<Button.Triggers>
      <EventTrigger RoutedEvent="Button.Click">
        <EventTrigger.Actions>
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation Storyboard.TargetProperty="Width"
                To="{Binding ElementName=window,Path=Width,Converter={StaticResource converter},ConverterParameter=-30}"
                               Duration="0:0:5"></DoubleAnimation>
              <DoubleAnimation Storyboard.TargetProperty="Height"
                To="{Binding ElementName=window,Path=Height,Converter={StaticResource converter},ConverterParameter=-50}"
                               Duration="0:0:5"></DoubleAnimation>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger.Actions>
      </EventTrigger>
    </Button.Triggers>

------------------使用Convert将String类型转换到需要类型

public class ArithmeticConverter : IValueConverter
    {
        private const string ArithmeticParseExpression = "([+\-*/]{1,1})\s{0,}(\-?[\d\.]+)";
        private Regex arithmeticRegex = new Regex(ArithmeticParseExpression);

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {

            if (value is double && parameter != null)
            {
                string param = parameter.ToString();

                if (param.Length > 0)
                {
                    Match match = arithmeticRegex.Match(param);
                    if (match != null && match.Groups.Count == 3)
                    {
                        string operation = match.Groups[1].Value.Trim();
                        string numericValue = match.Groups[2].Value;

                        double number = 0;
                        if (double.TryParse(numericValue, out number)) // this should always succeed or our regex is broken
                        {
                            double valueAsDouble = (double)value;
                            double returnValue = 0;

                            switch (operation)
                            {
                                case "+":
                                    returnValue = valueAsDouble + number;
                                    break;

                                case "-":
                                    returnValue = valueAsDouble - number;
                                    break;

                                case "*":
                                    returnValue = valueAsDouble * number;
                                    break;

                                case "/":
                                    returnValue = valueAsDouble / number;
                                    break;
                            }

                            return returnValue;
                        }
                    }
                }
            }

            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new Exception("The method or operation is not implemented.");
        }

    }

使用触发器进行触发:

<Style TargetType="ListBoxItem">
            <Style.Setters>
                <Setter Property="FontSize" Value="30"/>
            </Style.Setters>
            <Style.Triggers>
                <EventTrigger RoutedEvent="ListBoxItem.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard >
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="FontSize"
                                                 BeginTime="0:0:0.1"
                                                 Duration="0:0:0.2"
                                                 To="40"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="ListBoxItem.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard >
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="FontSize"
                                                 BeginTime="0:0:0.1"
                                                 Duration="0:0:0.2"
                                                 ></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>


四,控制动画---

image


制作界面:

image

1,界面元素:

5个按钮,对应Storyboard的效果:

<EventTrigger SourceName="cmdStart" RoutedEvent="Button.Click">
        <BeginStoryboard Name="fadeStoryboardBegin">
          <!-- The SpeedRatio binding makes sure the initial speed matches the slider.
               The Slider's event handling code makes sure the speed is updated when
               the slider is moved. -->
          <Storyboard Name="fadeStoryboard" CurrentTimeInvalidated="storyboard_CurrentTimeInvalidated"
                      SpeedRatio="{Binding ElementName=sldSpeed,Path=Value}">
            <DoubleAnimation
                Storyboard.TargetName="imgDay"
                Storyboard.TargetProperty="Opacity"
                From="1" To="0" Duration="0:0:10" RepeatBehavior="Forever" Completed="DoubleAnimation_Completed" ></DoubleAnimation>
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>

      <EventTrigger SourceName="cmdPause" RoutedEvent="Button.Click">
        <PauseStoryboard BeginStoryboardName="fadeStoryboardBegin"></PauseStoryboard>
      </EventTrigger>
      <EventTrigger SourceName="cmdResume" RoutedEvent="Button.Click">
        <ResumeStoryboard BeginStoryboardName="fadeStoryboardBegin"></ResumeStoryboard>
      </EventTrigger>
      <EventTrigger SourceName="cmdStop" RoutedEvent="Button.Click">
        <StopStoryboard BeginStoryboardName="fadeStoryboardBegin"></StopStoryboard>
      </EventTrigger>
      <EventTrigger SourceName="cmdMiddle" RoutedEvent="Button.Click">
        <SeekStoryboard BeginStoryboardName="fadeStoryboardBegin"
                        Offset="0:0:5"></SeekStoryboard>
      </EventTrigger>


使用这个画刷进行更新画面

<Grid>
    <Grid.RowDefinitions>
      <RowDefinition></RowDefinition>
      <RowDefinition Height="Auto"></RowDefinition>

    </Grid.RowDefinitions>
    <Grid>
      <Image Source="night.jpg"></Image>
      <Image Source="day.jpg" Name="imgDay">
        <Image.OpacityMask>
          <LinearGradientBrush StartPoint="0,0" EndPoint="1,0.2">
            <GradientStop Offset="0" Color="Transparent" x:Name="transparentStop" />
            <GradientStop Offset="0" Color="Black" x:Name="visibleStop" />
          </LinearGradientBrush>
        </Image.OpacityMask>
      </Image>
    </Grid>

      <Button Name="cmdStart" Grid.Row="1" Padding="5" Margin="5">
        Start
        <Button.Triggers>
          <EventTrigger SourceName="cmdStart" RoutedEvent="Button.Click">
            <BeginStoryboard>
              <Storyboard>
                <DoubleAnimation
                    Storyboard.TargetName="transparentStop"
                    Storyboard.TargetProperty="Offset" BeginTime="0:0:0.2"
                    From="0" To="1" Duration="0:0:1" ></DoubleAnimation>
                <DoubleAnimation
                    Storyboard.TargetName="visibleStop"
                    Storyboard.TargetProperty="Offset"
                    From="0" To="1.2" Duration="0:0:1.2" ></DoubleAnimation>
              </Storyboard>
            </BeginStoryboard>
          </EventTrigger>

        </Button.Triggers>
      </Button>




  </Grid>

4,通过事件更新信息:

image

 private void storyboard_CurrentTimeInvalidated(object sender, EventArgs e)
        {
            // Sender is the clock that was created for this storyboard.
            Clock storyboardClock = (Clock)sender;

            if (storyboardClock.CurrentProgress == null)
            {
                lblTime.Text = "[[ stopped ]]";
                progressBar.Value = 0;
            }
            else
            {
                lblTime.Text = storyboardClock.CurrentTime.ToString();
                progressBar.Value = (double)storyboardClock.CurrentProgress;
            }
        }

五,缓动函数:


 <Storyboard>
                                <DoubleAnimation
   Storyboard.TargetName="cmdGrow" Storyboard.TargetProperty="Width"
   To="400" Duration="0:0:1.5">
                                    <DoubleAnimation.EasingFunction>
                                        <ElasticEase EasingMode="EaseInOut" Oscillations="10" ></ElasticEase>
                                    </DoubleAnimation.EasingFunction>
                                </DoubleAnimation>
                            </Storyboard>

EasingMode:In,Out,InOut时候是效果不同的.

image


创建自定义函数:

public class RandomJitterEase : EasingFunctionBase
    {
        // Store a random number generator.
        private Random rand = new Random();

        protected override double EaseInCore(double normalizedTime)
        {
            //To see the values add code like this:
            //System.Diagnostics.Debug.WriteLine(...);

            // Make sure there's no jitter in the final value.
            if (normalizedTime == 1) return 1;

            // Offset the value by a random amount.
            return Math.Abs(normalizedTime - (double)rand.Next(0,10)/(2010 - Jitter));
        }

        public int Jitter
        {
            get { return (int)GetValue(JitterProperty); }
            set { SetValue(JitterProperty, value); }
        }

        public static readonly DependencyProperty JitterProperty =
            DependencyProperty.Register("Jitter", typeof(int), typeof(RandomJitterEase),
            new UIPropertyMetadata(1000), new ValidateValueCallback(ValidateJitter));

        private static bool ValidateJitter(object value)
        {
            int jitterValue = (int)value;
            return ((jitterValue <= 2000) && (jitterValue >= 0));
        }

        // This required override simply provides a live instance of your easing function.
        protected override Freezable CreateInstanceCore()
        {
            return new RandomJitterEase();
        }

       1,创建一个EasingFunctionBase 的派生类.

                      添加新的依赖性属性Jitter.

                     重写EaseInCore和CreateInstanceCore()函数.

然后,在xaml中进行引用.

xmlns:local="clr-namespace:Animation">


6,动画速率

<BeginStoryboard x:Key="beginStoryboard">
      <Storyboard Timeline.DesiredFrameRate="{Binding ElementName=txtFrameRate,Path=Text}">
        <DoubleAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Left)"
                         From="0" To="300" Duration="0:0:5">
        </DoubleAnimation>
        <DoubleAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Top)"
                         From="300" To="0" AutoReverse="True" Duration="0:0:2.5"
                         DecelerationRatio="1">
        </DoubleAnimation>
      </Storyboard>
    </BeginStoryboard>

7,位图缓存:

 PathGeometry pathGeometry = new PathGeometry();
            PathFigure pathFigure = new PathFigure();

            pathFigure.StartPoint = new Point(0,0);

            PathSegmentCollection pathSegmentCollection = new PathSegmentCollection();

            int maxHeight = (int)this.Height;
            int maxWidth = (int)this.Width;
            Random rand = new Random();
            for (int i = 0; i < 500; i++)
            {
                LineSegment newSegment = new LineSegment();
                newSegment.Point = new Point(rand.Next(0, maxWidth), rand.Next(0, maxHeight));
                pathSegmentCollection.Add(newSegment);
            }

            pathFigure.Segments = pathSegmentCollection;
            pathGeometry.Figures.Add(pathFigure);

            pathBackground.Data = pathGeometry;

使用代码创建背景

 private void chkCache_Click(object sender, RoutedEventArgs e)
        {
            if (chkCache.IsChecked == true)
            {
                BitmapCache bitmapCache = new BitmapCache();
                pathBackground.CacheMode = new BitmapCache();
            }
            else
            {
                pathBackground.CacheMode = null;
            }
        }
原文地址:https://www.cnblogs.com/frogkiller/p/13153112.html