WPF路径动画——C#篇

     在上一篇《WPF路径动画——XAML篇》中,所有的元素都是在XAML中定义的,用了少量的代码让动画运行起来。毕竟C#更灵活和动态,这次就重点用C#代码来完成动画,实现一个方块绕椭圆路径切线转动。

pgeUsingPath2.xaml

<Page x:Class="CnblogsDemo.pgeUsingPath2"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="500"    Title="路径动画使用C#"
      Loaded="Page_Loaded">

  <Grid ShowGridLines="True">
    <Grid.RowDefinitions>
      <RowDefinition Height="*"></RowDefinition>
      <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="3*"></ColumnDefinition>
      <ColumnDefinition Width="7*"></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <Canvas Name="mainCanvas" Grid.Row="0" Grid.Column="1" Background="LightCyan" Margin="50,30,0,0">
      <Canvas.Resources>
        <SolidColorBrush x:Key="PathStrokeBrush01" Color="#FF686964" />
      </Canvas.Resources>
      <Rectangle x:Name="rotatingLine" Width="80" Height="20" Stroke="Blue" Fill="Red" />
      <!--用来指示椭圆路径的中心点-->
      <Ellipse Name="ese1" Fill="red" Width="7" Height="7" Stroke="black" StrokeThickness="2.5" HorizontalAlignment="Left" VerticalAlignment="Top"></Ellipse>
    </Canvas>

  </Grid>
</Page>

============================================================

pgeUsingPath2.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace CnblogsDemo
{
    /// <summary>
    /// pgeUsingPath2.xaml 的交互逻辑
    /// </summary>
    public partial class pgeUsingPath2 : Page
    {
        public pgeUsingPath2()
        {
            InitializeComponent();
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            rotatingLine.RenderTransformOrigin = new Point(0.5, 0.5);
            Canvas.SetLeft(rotatingLine, -rotatingLine.ActualWidth * rotatingLine.RenderTransformOrigin.X);
            Canvas.SetTop(rotatingLine, -rotatingLine.ActualHeight * rotatingLine.RenderTransformOrigin.Y);
            MatrixTransform MatrixTransform_01 = new MatrixTransform();

            this.RegisterName("MatrixTransform_01", MatrixTransform_01);
            rotatingLine.RenderTransform = MatrixTransform_01;

            Point centerPt = new Point(150, 150);
            ese1.Margin = new Thickness(centerPt.X, centerPt.Y, 0, 0);                    //指示中心点
            Canvas.SetLeft(ese1, -ese1.ActualWidth / 2);
            Canvas.SetTop(ese1, -ese1.ActualHeight / 2);

            PathGeometry aniPath = new PathGeometry();
            EllipseGeometry egStandard = new EllipseGeometry(centerPt, 100, 80);
            aniPath.AddGeometry(egStandard);

            //外层
            Path ph = new Path();
            SolidColorBrush StrokeBrush = (SolidColorBrush)mainCanvas.Resources["PathStrokeBrush01"];
            ph.Stroke = StrokeBrush;
            ph.StrokeThickness = 1;
            EllipseGeometry eg2 = new EllipseGeometry(centerPt, egStandard.RadiusX + rotatingLine.ActualHeight / 2, egStandard.RadiusY + rotatingLine.ActualHeight / 2);
            ph.Data = eg2;
            mainCanvas.Children.Add(ph);

            //内层
            Path ph3 = new Path();
            ph3.Stroke = StrokeBrush;
            //ph.Fill = System.Windows.Media.Brushes.MediumSlateBlue;
            ph3.StrokeThickness = 1;
            EllipseGeometry eg3 = new EllipseGeometry(centerPt, egStandard.RadiusX - rotatingLine.ActualHeight / 2, egStandard.RadiusY - rotatingLine.ActualHeight / 2);
            ph3.Data = eg3;
            mainCanvas.Children.Add(ph3);

            Path phStandard = new Path();
            phStandard.Stroke = System.Windows.Media.Brushes.Blue;
            //ph.Fill = System.Windows.Media.Brushes.MediumSlateBlue;
            phStandard.StrokeThickness = 1;
            phStandard.Data = egStandard;
            mainCanvas.Children.Add(phStandard);

            MatrixAnimationUsingPath matrixAnimation = new MatrixAnimationUsingPath();
            matrixAnimation.PathGeometry = aniPath;                                //动画的路径
            matrixAnimation.Duration = TimeSpan.FromSeconds(10);
            matrixAnimation.RepeatBehavior = RepeatBehavior.Forever;
            matrixAnimation.DoesRotateWithTangent = true;                            

            Storyboard.SetTargetName(matrixAnimation, "MatrixTransform_01");                        //动画的对象
            Storyboard.SetTargetProperty(matrixAnimation, new PropertyPath(MatrixTransform.MatrixProperty));

            Storyboard pathAnimationStoryboard = new Storyboard();
            pathAnimationStoryboard.Children.Add(matrixAnimation);
            pathAnimationStoryboard.Begin(this);
        }
    }
}

   中间蓝色的路径是动画的路径,内层和外层用来体现路径和动画元素的相对关系,可以rotatingLine.RenderTransformOrigin改个其他值试试。
image
原文地址:https://www.cnblogs.com/edong/p/2658611.html