1. 程式人生 > 實用技巧 >WPF動畫基礎小例項 - Path相關PointAnimationUsingPath、DoubleAnimationUsingPath、MatrixAnimationUsingPath等

WPF動畫基礎小例項 - Path相關PointAnimationUsingPath、DoubleAnimationUsingPath、MatrixAnimationUsingPath等

動畫效果如下:

原始碼如下:

     <UniformGrid>
            <Canvas
                x:Name="cvs1"
                Width="340"
                Height="215"
                Margin="0"
                HorizontalAlignment="Left">
                <Path
                    x:Name="path1"
                    Margin
="0" HorizontalAlignment="Left" Data="M10,80 L120,80 180,200 300,200" Stroke="LightGreen" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeThickness
="5" /> </Canvas> <Canvas x:Name="cvs2" Width="340" Height="215" Margin="0" HorizontalAlignment="Left"> <Canvas.Triggers> <EventTrigger RoutedEvent
="Loaded"> <BeginStoryboard Name="MyStoryboard"> <Storyboard> <!-- Animates the button along the path. --> <PointAnimationUsingPath AutoReverse="True" RepeatBehavior="Forever" Storyboard.TargetName="myTransform" Storyboard.TargetProperty="Center" Duration="0:0:5"> <PointAnimationUsingPath.PathGeometry> <PathGeometry Figures="M10,100 L120,100 180,200 300,200" /> </PointAnimationUsingPath.PathGeometry> </PointAnimationUsingPath> </Storyboard> </BeginStoryboard> </EventTrigger> </Canvas.Triggers> <Path x:Name="path2" Margin="0" VerticalAlignment="Top" Data="M10,100 L120,100 180,200 300,200" Stroke="LightGreen" StrokeEndLineCap="Round" StrokeStartLineCap="Round" StrokeThickness="5" /> <Path Margin="0,0,0,5" Fill="Orange"> <Path.Data> <EllipseGeometry x:Name="myTransform" Center="5,100" RadiusX="5" RadiusY="5" /> </Path.Data> <!--<Path.RenderTransform> <MatrixTransform x:Name="myTransform"> <MatrixTransform.Matrix> <Matrix OffsetX="10" OffsetY="100" /> </MatrixTransform.Matrix> </MatrixTransform> </Path.RenderTransform>--> </Path> </Canvas> <Canvas Width="340" Height="240" HorizontalAlignment="Left"> <Canvas.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard> <Storyboard> <!-- Animates the button along the path. --> <MatrixAnimationUsingPath AutoReverse="True" RepeatBehavior="Forever" Storyboard.TargetName="myMatrixTransform" Storyboard.TargetProperty="Matrix" Duration="0:0:5"> <MatrixAnimationUsingPath.PathGeometry> <PathGeometry Figures="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" /> </MatrixAnimationUsingPath.PathGeometry> </MatrixAnimationUsingPath> </Storyboard> </BeginStoryboard> </EventTrigger> </Canvas.Triggers> <!-- This Path is only to show the path that the animated object will follow. --> <Path Margin="15,15,15,15" VerticalAlignment="Top" Data="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" Stretch="None" Stroke="Black" StrokeThickness="2" /> <!-- The Button that is animated across the screen. --> <Path Margin="0,0,15,15" Fill="Blue"> <Path.Data> <RectangleGeometry x:Name="MyAnimatedRectGeometry" Rect="0,0 30 30" /> </Path.Data> <Path.RenderTransform> <MatrixTransform x:Name="myMatrixTransform"> <MatrixTransform.Matrix> <Matrix OffsetX="10" OffsetY="100" /> </MatrixTransform.Matrix> </MatrixTransform> </Path.RenderTransform> </Path> </Canvas> <Canvas Width="340" Height="215" Margin="0" HorizontalAlignment="Left"> <Canvas.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard Name="MyBeginStoryboard"> <Storyboard> <!-- Animates the rectangle horizotally along the path. --> <DoubleAnimationUsingPath AutoReverse="False" RepeatBehavior="Forever" Source="X" Storyboard.TargetName="MyAnimatedTransform" Storyboard.TargetProperty="X" Duration="0:0:5"> <DoubleAnimationUsingPath.PathGeometry> <PathGeometry Figures="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" /> </DoubleAnimationUsingPath.PathGeometry> </DoubleAnimationUsingPath> <!-- Animates the rectangle vertically along the path. --> <DoubleAnimationUsingPath AutoReverse="False" RepeatBehavior="Forever" Source="Y" Storyboard.TargetName="MyAnimatedTransform" Storyboard.TargetProperty="Y" Duration="0:0:5"> <DoubleAnimationUsingPath.PathGeometry> <PathGeometry Figures="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" /> </DoubleAnimationUsingPath.PathGeometry> </DoubleAnimationUsingPath> <ColorAnimation AutoReverse="True" RepeatBehavior="Forever" Storyboard.TargetName="opacityAnimatedColorRectangle" Storyboard.TargetProperty="(Rectangle.Fill).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)" Duration="0:0:5"> <ColorAnimation.By> <Color ScA="-1.0" ScB="0.0" ScG="0.0" ScR="0.0" /> </ColorAnimation.By> </ColorAnimation> </Storyboard> </BeginStoryboard> </EventTrigger> </Canvas.Triggers> <!-- This Path is only to show the path that the animated object will follow. --> <Path Name="opacityAnimatedColorRectangle" Margin="15,15,15,15" VerticalAlignment="Top" Data="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" Stretch="None" Stroke="Black" StrokeThickness="2"> <Path.Fill> <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.0" Color="Green" /> <GradientStop Offset="0.75" Color="LightGreen" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <!-- This geometry renders the rectangle that is animated across the screen. --> <Path Margin="0,0,15,15" Fill="Blue"> <Path.Data> <RectangleGeometry x:Name="MyAnimatedRectGeometryX" Rect="0,0 30 30" /> </Path.Data> <Path.RenderTransform> <TranslateTransform x:Name="MyAnimatedTransform" X="10" Y="100" /> </Path.RenderTransform> </Path> </Canvas> </UniformGrid>

        /// <summary>
        /// 後臺設定動畫
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            AnimationByPath(cvs1, path1, path1.StrokeThickness);
        }

        /// <summary>
        /// 路徑動畫
        /// </summary>
        /// <param name="cvs">畫板</param>
        /// <param name="path">路徑</param>
        /// <param name="target">動畫物件</param>
        /// <param name="duration">時間</param>
        private void AnimationByPath(Canvas cvs, Path path, double targetWidth, int duration = 5)
        {
            #region 建立動畫物件
            Rectangle target = new Rectangle();
            target.Width = targetWidth;
            target.Height = targetWidth;
            target.Fill = new SolidColorBrush(Colors.Orange);

            DropShadowEffect effect = new DropShadowEffect();
            effect.Color = Colors.Red;
            effect.BlurRadius = 5;
            effect.ShadowDepth = 0;
            effect.Direction = 0;
            target.Effect = effect;

            cvs.Children.Add(target);
            Canvas.SetLeft(target, -targetWidth / 2);
            Canvas.SetTop(target, -targetWidth / 2);
            target.RenderTransformOrigin = new Point(0.5, 0.5);
            #endregion

            MatrixTransform matrix = new MatrixTransform();
            TransformGroup groups = new TransformGroup();
            groups.Children.Add(matrix);
            target.RenderTransform = groups;
            string registname = "matrix" + Guid.NewGuid().ToString().Replace("-", "");
            this.RegisterName(registname, matrix);
            MatrixAnimationUsingPath matrixAnimation = new MatrixAnimationUsingPath();
            matrixAnimation.PathGeometry = PathGeometry.CreateFromGeometry(Geometry.Parse(path.Data.ToString()));
            matrixAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration));
            matrixAnimation.DoesRotateWithTangent = true;//跟隨路徑旋轉
            matrixAnimation.RepeatBehavior = RepeatBehavior.Forever;//迴圈
            Storyboard story = new Storyboard();
            story.Children.Add(matrixAnimation);
            Storyboard.SetTargetName(matrixAnimation, registname);
            Storyboard.SetTargetProperty(matrixAnimation, new PropertyPath(MatrixTransform.MatrixProperty));

            story.FillBehavior = FillBehavior.Stop;
            story.Begin(target, true);
        }