C# 弯曲并跟随某些路径几何体的WPF动画
好的,我正在处理一个加载屏幕,我想把它放大一点 基本上,我想做的是沿路径几何体数据设置对象动画…我强调“沿”,因为我不想沿切线上的路径保持固定对象 这是我试图做的最好的表现: 我可以使用矩阵变换沿路径发送此边界元素,但它最终显示为切线动画,随路径移动和旋转,但不会弯曲以适应路径的形状…以下是一个示例:C# 弯曲并跟随某些路径几何体的WPF动画,c#,wpf,animation,C#,Wpf,Animation,好的,我正在处理一个加载屏幕,我想把它放大一点 基本上,我想做的是沿路径几何体数据设置对象动画…我强调“沿”,因为我不想沿切线上的路径保持固定对象 这是我试图做的最好的表现: 我可以使用矩阵变换沿路径发送此边界元素,但它最终显示为切线动画,随路径移动和旋转,但不会弯曲以适应路径的形状…以下是一个示例: <Border Background="Black" BorderBrush="Transparent" Width="20" Height="20"> <Border.Ren
<Border Background="Black" BorderBrush="Transparent" Width="20" Height="20">
<Border.RenderTransform>
<MatrixTransform x:Name="MatrixT">
<MatrixTransform.Matrix>
<Matrix/>
</MatrixTransform.Matrix>
</MatrixTransform>
</Border.RenderTransform>
<Border.Triggers>
<EventTrigger RoutedEvent="Border.Loaded">
<BeginStoryboard>
<Storyboard>
<MatrixAnimationUsingPath Storyboard.TargetName="MatrixT" Storyboard.TargetProperty="Matrix" DoesRotateWithTangent="True" Duration="0:0:5" RepeatBehavior="Forever">
<MatrixAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M201.1,50.501C201.1,78.138,178.737,100.501,151.1,100.501L150.799,100.501C123.162,100.501,114.933,77.834,100.8,50.501L100.8,50.5C86.666,23.167,78.437,0.5,50.8,0.5L50.5,0.5C22.863,0.5,0.500000000000014,22.863,0.500000000000014,50.5L0.500000000000014,50.501C0.500000000000014,78.138,22.863,100.501,50.5,100.501L50.8,100.501C78.437,100.501,86.666,77.834,100.8,50.501L100.8,50.5C114.933,23.167,123.162,0.5,150.799,0.5L151.1,0.5C178.736,0.5,201.1,22.863,201.1,50.501L201.1,50.501z" PresentationOptions:Freeze="True"/>
</MatrixAnimationUsingPath.PathGeometry>
</MatrixAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
我提出了一个看起来非常尖锐的替代解决方案,但我想向社区提出这个问题,看看他们对如何完成这项任务是否有任何想法(或者是否可能)…我在谷歌上做了大量的搜索,但没有找到有效的方法来实现这一点
要求:
您可以在路径上放置许多圆并设置其直径的动画。在WPF中,将形状变形为路径将非常困难。但是,通过设置两条单独路径的动画,以及同时设置两个剪裁区域的动画,可以实现近似效果 下面给出的是您想要的近似值的XAML。如果仔细观察无限符号的交叉点,您将注意到过渡期间着色的平滑度有轻微的不连续性。这是因为我对
LinearGradientBrush
对象的起点、终点和偏移点的设置有点随意。在这些方面做一点工作将使过渡顺利进行。您甚至可以选择为笔刷上的属性设置动画来帮助实现这一点
<Window x:Class="AnimationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Background="#FF486CBF">
<Viewbox>
<Grid>
<Canvas Width="50" Height="50"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,50,55">
<RectangleGeometry.Transform>
<TranslateTransform x:Name="_clip1"/>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Canvas.Clip>
<Path StrokeStartLineCap="Round"
StrokeEndLineCap="Round"
StrokeThickness="10"
RenderTransformOrigin="0.5,0.8571"
Data="M 5,25 c 0,-25 40,-25 40,0">
<Path.Stroke>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#00FFFFFF" Offset="0.7"/>
</LinearGradientBrush>
</Path.Stroke>
<Path.RenderTransform>
<RotateTransform x:Name="_rot1" />
</Path.RenderTransform>
<Path.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="360" To="0"
Duration="0:0:3"
RepeatBehavior="Forever"
Storyboard.TargetName="_rot1"
Storyboard.TargetProperty="Angle"/>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="_clip1"
Storyboard.TargetProperty="Y"
RepeatBehavior="Forever">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:1.5" Value="25"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:2.8" Value="55"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:4.5" Value="-30"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:5.8" Value="0"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:6" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
<Canvas Width="50" Height="50"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="40,0,0,0">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,50,55">
<RectangleGeometry.Transform>
<TranslateTransform x:Name="_clip2"/>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Canvas.Clip>
<Path StrokeStartLineCap="Round"
StrokeEndLineCap="Round"
StrokeThickness="10"
RenderTransformOrigin="0.5,0.8571"
Data="M 5,25 c 0,-25 40,-25 40,0">
<Path.Stroke>
<LinearGradientBrush StartPoint="1,0" EndPoint="0,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#00FFFFFF" Offset="0.7"/>
</LinearGradientBrush>
</Path.Stroke>
<Path.RenderTransform>
<RotateTransform x:Name="_rot2" />
</Path.RenderTransform>
<Path.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="0" To="360"
Duration="0:0:3"
RepeatBehavior="Forever"
Storyboard.TargetName="_rot2"
Storyboard.TargetProperty="Angle"/>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="_clip2"
Storyboard.TargetProperty="Y"
RepeatBehavior="Forever">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="55"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:1.5" Value="-30"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:2.8" Value="0"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:4.5" Value="25"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:5.8" Value="55"/>
<DiscreteDoubleKeyFrame KeyTime="0:0:6" Value="55"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
</Grid>
</Viewbox>
</Window>
需要注意的一点是,需要将剪裁区域应用于
画布
对象。如果它们应用于路径
对象,就像通常对图像所做的那样,则剪裁区域将通过渲染器窗体
随路径
旋转。不是期望的效果。您是否尝试过PathListbox hmmm…这是一个有趣的控件,我还没有见过,实际上我还有一些其他用途…但它最终仍然不允许对象沿路径弯曲/弯曲,沿着它切向旋转这实际上是在做你想做的事情,只需做一点谷歌搜索。我似乎仍然找不到任何与我想用它搜索的内容相关的东西…请看我刚才添加到问题中的第二张图片…PathListBox似乎允许你沿一条路径放置一组显示元素,但它不会扭曲元素的外观,使其沿路径弯曲(在旋转/平移/缩放之外),技术上,这是一个答案,但这并不理想…必须有更好的方法来完成此任务…另外,除非你把它放在超小的范围内,否则你必须要有很多圆圈才能看到它不是一条平滑的线。这取决于你认为什么是理想的和动画有多大。我目前的解决方案是使用一组7或8个圆,它们沿着路径并相互跟踪(彼此之间有空格),有点像你的解决方案……不过我要寻找的是一种使用路径几何体变形对象的方法,这不仅仅对动画很有用…我有一个很好的感觉,这是不可能的开箱即用,但是,如果我没有得到任何解决方案,这在未来几天左右,我会把这作为一个正确的问题的答案。“开箱即用”不可用。遵循一条路径是可能的:变形是一个不同的野兽:当一个片段位于非常锋利的边缘时会发生什么?是的,变形肯定会有挑战,但拥有这种能力仍然是有用的…锋利的边缘是一个问题,但这更像是一个不正确使用功能的问题,而不是一个问题