2015-07-11 153 views
1

我在XAML中使用沿着圆形Path移动的ArcSegment构建了一个微调器图标。过了一段时间,我希望我的微调体积增大以创造一个完整的圆圈。将旋转ArcSegment旋转成整圈

这是我的动画看起来像,而它的运动(抖动现象是由于桌面捕获):enter image description here

我会解释我的思维过程。我们可以在旋转随机点看一看图像,谈谈我们会如何成长为一个完整的圆:

  • 半径:10
  • 帆布:22×22
  • 弧StartPoint可以: 18.071,3.929
  • 弧终点:22,11

Sample Circle

我相信,我只需要使用一个故事板w^ith PointAnimationUsingPath(22,11)(18.071,3.929)顺时针方向。

我的问题是:如何创建基于我的ArcSegment的当前值创建的PointAnimationUsingPath

我已经包含了XAML。如果有什么需要澄清,让我知道。

<UserControl x:Class="TestingIcons.icons.Processing" 
      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:local="clr-namespace:TestingIcons.icons" 
      xmlns:sysWin="clr-namespace:System.Windows;assembly=WindowsBase" 
      mc:Ignorable="d" 
      Background="White" 
      d:DesignHeight="22" d:DesignWidth="22"> 

    <UserControl.Resources> 
     <sysWin:Point x:Key="topCenterPoint">11 1</sysWin:Point> 
     <sysWin:Point x:Key="topRightPoint">18.071 3.929</sysWin:Point> 
     <sysWin:Point x:Key="bottomCenterPoint">11 21</sysWin:Point> 
     <sysWin:Point x:Key="bottomLeftPoint">3.929 18.071</sysWin:Point> 
     <sysWin:Size x:Key="circleSize">10 10</sysWin:Size> 

     <Storyboard x:Key="SpinningAnimation"> 
      <DoubleAnimation 
       Storyboard.TargetName="outerPath" 
       Storyboard.TargetProperty="Opacity" 
       From="1" To="0" Duration="0:0:0.5"/> 

      <!--Reset the arc to a single point--> 
      <PointAnimationUsingKeyFrames 
       Storyboard.TargetName="startArc" 
       Storyboard.TargetProperty="StartPoint" 
       > 
       <!--Always grow the arc from its starting position--> 
       <DiscretePointKeyFrame KeyTime="0:0:0" Value="{StaticResource topCenterPoint}"/> 
      </PointAnimationUsingKeyFrames> 
      <!-- Grow the arc from a point --> 
      <PointAnimationUsingPath 
       Storyboard.TargetName="endArc" 
       Storyboard.TargetProperty="Point" 
       Duration="0:0:0.2" 
       AccelerationRatio="0.5"> 
       <PointAnimationUsingPath.PathGeometry> 
        <PathGeometry> 
         <PathFigure StartPoint="{StaticResource topCenterPoint}" IsClosed="False"> 
          <ArcSegment 
           Point="{StaticResource topRightPoint}" 
           Size="{StaticResource circleSize}" 
           IsLargeArc="False" 
           SweepDirection="Clockwise" /> 
         </PathFigure> 
        </PathGeometry> 
       </PointAnimationUsingPath.PathGeometry> 
      </PointAnimationUsingPath> 

      <!--Animate the start of the arc in a circle--> 
      <PointAnimationUsingPath 
       Storyboard.TargetName="startArc" 
       Storyboard.TargetProperty="StartPoint" 
       Duration="0:0:0.8" 
       BeginTime="0:0:0.2" 
       AccelerationRatio="0.4" 
       > 
       <PointAnimationUsingPath.PathGeometry> 
        <PathGeometry> 
         <PathFigure StartPoint="{StaticResource topCenterPoint}"> 
          <ArcSegment Size="{StaticResource circleSize}" Point="{StaticResource bottomCenterPoint}" 
              SweepDirection="Clockwise" /> 
          <ArcSegment Size="{StaticResource circleSize}" Point="{StaticResource topCenterPoint}" 
              SweepDirection="Clockwise" /> 
         </PathFigure> 
        </PathGeometry> 
       </PointAnimationUsingPath.PathGeometry> 
      </PointAnimationUsingPath> 

      <!-- Animate the end of the arc in a circle--> 
      <PointAnimationUsingPath 
        Storyboard.TargetName="endArc" 
        Storyboard.TargetProperty="Point" 
        Duration="0:0:0.8" 
        BeginTime="0:0:0.2" 
        AccelerationRatio="0.4" 
        > 
       <PointAnimationUsingPath.PathGeometry> 
        <PathGeometry> 
         <PathFigure StartPoint="{StaticResource topRightPoint}"> 
          <ArcSegment Size="{StaticResource circleSize}" Point="{StaticResource bottomLeftPoint}" 
               SweepDirection="Clockwise" /> 
          <ArcSegment Size="{StaticResource circleSize}" Point="{StaticResource topRightPoint}" 
               SweepDirection="Clockwise" /> 
         </PathFigure> 
        </PathGeometry> 
       </PointAnimationUsingPath.PathGeometry> 
      </PointAnimationUsingPath> 
     </Storyboard> 
    </UserControl.Resources> 

    <UserControl.Triggers> 
     <EventTrigger RoutedEvent="Window.MouseEnter"> 
      <BeginStoryboard Storyboard="{StaticResource SpinningAnimation}"/> 
     </EventTrigger> 
    </UserControl.Triggers> 

    <Canvas> 
     <Path x:Name="outerPath" Stroke="Black" StrokeThickness="1"> 
      <Path.Data> 
       <PathGeometry> 
        <PathFigure StartPoint="{StaticResource topCenterPoint}"> 
         <ArcSegment Size="{StaticResource circleSize}" Point="{StaticResource bottomCenterPoint}" SweepDirection="Clockwise"/> 
         <ArcSegment Size="{StaticResource circleSize}" Point="{StaticResource topCenterPoint}" SweepDirection="Clockwise"/> 
        </PathFigure> 
       </PathGeometry> 
      </Path.Data> 
     </Path> 

     <Path x:Name="eighthOfCircle" Stroke="Black" StrokeThickness="1"> 
      <Path.Data> 
       <PathGeometry> 
        <PathFigure x:Name="startArc" StartPoint="{StaticResource topCenterPoint}" IsClosed="False"> 
         <ArcSegment x:Name="endArc" 
           Point="{StaticResource topRightPoint}" 
           Size="{StaticResource circleSize}" 
           IsLargeArc="False" 
           SweepDirection="Clockwise" /> 
        </PathFigure> 
       </PathGeometry> 
      </Path.Data> 
     </Path> 
    </Canvas> 
</UserControl> 
+0

请注意,一旦弧段覆盖超过180°,这将变得困难。然后您将不得不切换IsLargeArc属性。 – Clemens

+0

是的,但我想可以使用'BooleanAnimationUsingKeyFrames'在故事板的中途切换'IsLargeArc'。 – JoshVarty

回答

1

如果您安装了用于Visual Studio的Blend,请在该处打开您的项目,您会看到形状有更多选项。例如:

<ed:Arc ArcThickness="20" 
     ArcThicknessUnit="Pixel" 
     EndAngle="270" 
     Fill="#FFF4F4F5" 
     HorizontalAlignment="Left" 
     Height="100" 
     Stretch="None" 
     Stroke="Black" 
     StartAngle="0" 
     VerticalAlignment="Top" 
     Width="100"/> 

通过混合引入的命名空间为:

xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" 

而且它增加了一个参考:

Microsoft.Expression.Drawing 

有了那个形状,你可以动画的起点和终点角度使弧线增长。 下面是一个示例:

<ContentControl> 
    <ContentControl.Template> 
     <ControlTemplate 
      TargetType = "{x:Type ContentControl}"> 
      <ControlTemplate.Resources> 
       <Storyboard 
        x:Key = "TheAnimation"> 
        <DoubleAnimation 
         Storyboard.TargetName = "TheArc" 
         Storyboard.TargetProperty = "EndAngle" 
         From = "0" 
         To = "360" 
         RepeatBehavior = "Forever" 
         Duration = "0:0:1"/> 
        <DoubleAnimation 
         Storyboard.TargetName = "TheRotationTransform" 
         Storyboard.TargetProperty = "Angle" 
         From = "0" 
         To = "360" 
         RepeatBehavior = "Forever" 
         Duration = "0:0:1"/> 
       </Storyboard> 
      </ControlTemplate.Resources> 
      <ControlTemplate.Triggers> 
       <Trigger 
        Property = "Visibility" 
        Value = "Visible"> 
        <Trigger.ExitActions> 
         <StopStoryboard 
          BeginStoryboardName = "TheAnimation_BeginStoryboard"/> 
        </Trigger.ExitActions> 
        <Trigger.EnterActions> 
         <BeginStoryboard 
          x:Name = "TheAnimation_BeginStoryboard" 
          Storyboard = "{StaticResource TheAnimation}"/> 
        </Trigger.EnterActions> 
       </Trigger> 
      </ControlTemplate.Triggers> 
      <Border 
       Height = "100" 
       Width = "100" 
       RenderTransformOrigin = "0.5,0.5"> 
       <ed:Arc 
        x:Name = "TheArc" 
        ArcThickness = "10" 
        ArcThicknessUnit = "Pixel" 
        Fill = "Blue" 
        EndAngle = "90" 
        Height = "100" 
        HorizontalAlignment = "Right" 
        StartAngle = "0" 
        Stretch = "None" 
        VerticalAlignment = "Top" 
        Width = "100"/> 
       <Border.RenderTransform> 
        <TransformGroup> 
         <RotateTransform 
          x:Name = "TheRotationTransform" 
          Angle = "0"/> 
        </TransformGroup> 
       </Border.RenderTransform> 
      </Border> 
     </ControlTemplate> 
    </ContentControl.Template> 
</ContentControl> 
+0

我正在使用类似的东西。 (ArgSegment)使用它们,我需要访问正在旋转的圆弧的当前位置。这是我正在努力的部分。 – JoshVarty

+0

使用旋转变换对旋转进行动画处理,它们只是将结束角度从0更新到360,它应该可以工作,我会发布一个示例。 –

+0

这个问题并没有围绕它旋转。这个问题正在从目前的状况发展成一个完整的循环。 (它可能会在任何时候旋转) – JoshVarty