首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >弯曲并跟随某些路径几何体的WPF动画

弯曲并跟随某些路径几何体的WPF动画
EN

Stack Overflow用户
提问于 2013-06-14 02:02:09
回答 2查看 3.5K关注 0票数 19

好的,我正在做一个加载屏幕,我想把它放大一点。

基本上,我要做的就是沿着路径几何数据为一个对象设置动画……我强调“沿着”是因为我不想让一个固定的对象沿着路径保持在切线上

这是我想要做的最好的表现:

我可以使用矩阵变换来沿着路径发送这个边界元素,但它最终变成了一个与路径一起移动和旋转的切线动画,但不弯曲以适合path...Here的形状就是一个例子:

代码语言:javascript
复制
<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>

我已经提出了一个看起来非常尖锐的替代解决方案,但我想向社区提出这个问题,看看他们是否有任何关于如何完成这项任务的想法(或者它是否可能)...I在这个问题上做了大量的谷歌搜索,但没有提出如何以有效的方式完成这一任务。

要求:

  1. 它必须遵循路径
  2. 它必须能够在不破坏动画的情况下缩放大小(我见过的许多笔画动画表示在不重新配置动画属性的情况下只能以一种大小运行)...a viewbox完全可以实现此

如果形状可以逐渐变细并在后方淡出,这将是一个更大的优势(见上图),但这可能比可能的更多。

编辑:为了澄清我所说的“弯曲”是什么意思,我的意思是图B below...figure A是我传统上看到的标准:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-14 19:49:16

在WPF中将形状变形为路径将是非常困难的。但是,通过为两个单独的路径设置动画,并同时设置两个剪切区域的动画,可以实现近似。

下面给出的XAML是您想要的近似值。如果仔细观察无穷大符号的交叉点,您将注意到在过渡期间着色的平滑度略有中断。这是因为我对LinearGradientBrush对象的起始点、结束点和偏移点的设置有点随意。在这些方面做一些工作将使这种过渡变得平滑。您甚至可以选择在笔刷上设置属性动画来帮助实现此目的。

代码语言:javascript
复制
<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>

需要注意的重要一点是,需要将裁剪区域应用于Canvas对象。如果它们被应用于Path对象,就像您通常对图像所做的那样,则剪切区域随后由RenderTrasformPath一起旋转。不是想要的效果。

票数 4
EN

Stack Overflow用户

发布于 2013-06-14 03:20:51

您只需在路径上放置许多圆,并设置其直径的动画。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17093975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档