PageMain.xaml
<Page x:Class="CnblogsDemo.PageMain" 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" xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="500" Title="我的主页" 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> <!--==============================================================================================--> <Grid Name="grid3" Grid.Row="1" Grid.Column="1" > <Grid.Resources> <PathGeometry x:Key="Path_02" Figures="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" PresentationOptions:Freeze="True"/> <Storyboard x:Key="ourStoryboard"> <MatrixAnimationUsingPath Storyboard.TargetName="MatrixTransform_02" DoesRotateWithTangent="True" AutoReverse="True" Storyboard.TargetProperty="Matrix" Duration="00:00:5" RepeatBehavior="Forever" PathGeometry="{StaticResource Path_02}" /> </Storyboard> </Grid.Resources> <Canvas Width="200" Height="200" Background="LightCyan" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,30,0,0"> <Path Data="{StaticResource Path_02}" Stroke="Red" /> <Rectangle x:Name="rotatingLine3" Width="60" Height="30" Stroke="Blue" Fill="green" RadiusX="8" RadiusY="8" > <Rectangle.RenderTransform> <MatrixTransform x:Name="MatrixTransform_02" /> </Rectangle.RenderTransform> </Rectangle> </Canvas> </Grid> </Grid> </Page> ================================================================================
PageMain.xaml.cs
using System.Windows; using System.Windows.Controls; using System.Windows.Media.Animation; namespace CnblogsDemo { public partial class PageMain : Page { public PageMain() { InitializeComponent(); } private void Page_Loaded(object sender, RoutedEventArgs e) { Point ptOrigin = new Point(0.5, 1); rotatingLine3.RenderTransformOrigin = ptOrigin; Canvas.SetLeft(rotatingLine3, -rotatingLine3.ActualWidth * ptOrigin.X); Canvas.SetTop(rotatingLine3, -rotatingLine3.ActualHeight * ptOrigin.Y); Storyboard sbd = (Storyboard)grid3.Resources["ourStoryboard"]; sbd.Begin(this); } } }
================================================================================
动画元素需要放在Canvas里整体处理,Canvas是个绝对定位的工具,可以看到它的大小、Margin对内部没有影响。把PathGeometry做成一个静态资源,路径动画MatrixAnimationUsingPath使用,Canvas中的Path显示出了这个路径。
在代码中有一个重要的工作,设置RenderTransformOrigin变换中心点,这是一个Point,它的值是相对的,即变换中心点对于长、宽的比例,此点会保持在路径上。
这里想提一次周银辉的博客(他的博客我很喜欢)。
http://www.cnblogs.com/zhouyinhui/archive/2007/07/31/837893.html
图中方块运动的路径与曲线并为完全重合,而是存在X与Y方向上的平移。这是一个很让人头疼的问题,但是我发现,只要在动画播放之前,将方块的中心位置设置为与动画所在容器的(0,0)位置相重合,那么该问题就可以被避免。
这里讲“中心位置设置为与动画所在容器的(0,0)位置向重合”,原因是将RenderTransformOrigin设置成了0.5,0.5,就是方块的中心点。
如果像我的代码RenderTransformOrigin设置成了(0.5,1),是底边中点,方块在路径上方运行且始终与路径相切。所以应该是RenderTransformOrigin变换中心点与动画所在容器的(0,0)位置重合。