逐渐停止代码中的旋转(WPF动画)

本文关键字:旋转 WPF 动画 代码 | 更新日期: 2023-09-27 18:25:08

我需要在代码中逐步开始和停止动画(旋转)。

首先,我制作了下一个故事板:

DoubleAnimation StartRotating = new DoubleAnimation();
StartRotating.From = 0;
StartRotating.To = 360;
StartRotating.Duration = TimeSpan.FromSeconds(2);
control.storyboard.Children.Add(StartRotating);
Storyboard.SetTarget(StartRotating, control.FanCanvas);
Storyboard.SetTargetProperty(StartRotating, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"));
PowerEase easingFunction = new PowerEase();
easingFunction.EasingMode = EasingMode.EaseIn;
StartRotating.EasingFunction = easingFunction;
DoubleAnimationUsingKeyFrames persistentRotation = new DoubleAnimationUsingKeyFrames();
persistentRotation.BeginTime = TimeSpan.FromSeconds(2);
persistentRotation.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTarget(persistentRotation, control.FanCanvas);
Storyboard.SetTargetProperty(persistentRotation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"));
persistentRotation.KeyFrames.Add(new EasingDoubleKeyFrame(360, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
persistentRotation.KeyFrames.Add(new EasingDoubleKeyFrame(720, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1))));
control.storyboard.Children.Add(persistentRotation);
control.storyboard.Begin();

我需要在一瞬间逐渐停止它。然而,我有一些问题:

1) 我无法获得当前Angle的值。我尝试过这个解决方案(如何在WPF中获得UI元素的旋转值),但值rotation为空。。。所以,我无法获得Angle

2) 然后我想逐渐停止动画,我改变我的故事板,然后停止,然后重新开始。所以,它有一个小的停顿。然而,我希望有一个平滑的动画没有停顿。

提前谢谢。

逐渐停止代码中的旋转(WPF动画)

要平滑地更改动画的速度,有两个主要选项。第一个使用可用的Easing函数,如ExponentialEase类(示例取自此链接页面):

<Rectangle Name="myRectangle" Width="200" Height="30" Fill="Blue">
    <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Rectangle.MouseDown">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                     Storyboard.TargetName="myRectangle" 
                     Storyboard.TargetProperty="Height">
                        <DoubleAnimation.EasingFunction>
                            <ExponentialEase Exponent="6" EasingMode="EaseOut"/>
                        </DoubleAnimation.EasingFunction>
                    </DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>
</Rectangle>

另一个简单得多但不可配置的选项是对所使用的Animation对象使用Timeline.DecelerationRatio属性。

虽然我看到您正在使用EasingMode属性,但我想补充一点,当使用KeyFrame s时,要获得平滑的动画更改会有些困难。


更新>>>

您应该能够从RenderTransform属性中找到RotateTransform的当前值,如下所示:

double currentRotationValue = 0;
TransformGroup transformGroup = element.RenderTransform as TransformGroup;
if (transformGroup != null)
{
    RotateTransform rotateTransform = transformGroup.Children[2] as RotateTransform;
    if (rotateTransform != null)
    {
        currentRotationValue = rotation.Angle;
    }
}
// Use currentRotationValue for whatever you want

这显然假设您的RotationTransform位于TransformGroup元素的第三个位置。如果不是这样,那么在运行之前需要调整此代码。