【问题标题】:Grow spinning ArcSegment into full circle将旋转的 ArcSegment 变成一个完整的圆圈
【发布时间】:2015-09-30 12:02:30
【问题描述】:

我在 XAML 中使用一个沿圆形 Path 移动的 ArcSegment 构建了一个小微调器图标。一段时间后,我希望我的微调器变大以形成一个完整的圆圈。

这是我的动画在移动时的样子(断断续续是由于桌面捕获造成的):

我将解释我的思考过程。我们可以看看旋转时随机点的图像,然后讨论我们如何将它变成一个完整的圆圈:

  • 半径:10
  • 画布:22x22
  • 圆弧起点:18.071, 3.929
  • 圆弧端点:22,11

我相信我只需要使用带有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>

【问题讨论】:

  • 请注意,一旦弧段覆盖超过 180°,这将变得困难。然后,您还必须切换 IsLargeArc 属性。
  • 是的,但我认为可以使用BooleanAnimationUsingKeyFrames 在情节提要的中途切换IsLargeArc

标签: wpf xaml animation storyboard


【解决方案1】:

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

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

blend引入的命名空间是:

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>

【讨论】:

  • 我正在使用类似的东西。 (ArgSegment)使用它们,我需要访问正在旋转的圆弧的当前位置。这就是我正在努力解决的部分。
  • 使用旋转变换动画旋转,他们只是将结束角度从 0 更新到 360,它应该可以工作,我会发布一个例子。
  • 问题不在于将其旋转一圈。问题是把它从目前的位置发展成一个完整的循环。 (它可以在任何时候旋转)
  • 我更新了我的答案,这个例子有一个旋转和增长的弧,这里的关键是我在弧上设置了 Stretch 为 None。
猜你喜欢
  • 1970-01-01
  • 2019-04-25
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 2021-07-30
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
相关资源
最近更新 更多