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改个其他值试试。