【问题标题】:Sliding elements in c# UWPc# UWP中的滑动元素
【发布时间】:2018-01-11 02:59:05
【问题描述】:

我对 UWP 中的动画有疑问。我想在我的应用程序底部有一个菜单,当点击顶部时,它会向上滑动(显示)或向下滑动(几乎完全隐藏)。我之前在学习 WPF,在那里我知道我可以使用 ThicknessAnimation 来移动我的控件的边距并让它滑动。不幸的是,在 UWP 中我不能使用 ThicknessAnimations,所以我试图找到另一种方法。我希望这适用于任意 FrameworkElement(以便能够重用它)。最终,我想出了这个解决方案:

    /// <summary>
    /// Adds a vertical slide animation
    /// </summary>
    /// <param name="storyboard">The storyboard to add the animation to</param>
    /// <param name="seconds">The time the animation will take</param>
    /// <param name="offset">The distance the element will cover (nagative is up, positive is down)</param>
    public static void AddVerticalSlide(this Storyboard storyboard, FrameworkElement element, float seconds, double offset)
    {

        var slideAnimation = new ObjectAnimationUsingKeyFrames();       

        for (int i = 0; i <= 100; ++i)
        {
            double scalar = (double)i / 100;
            slideAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame
            {                   
                Value = new Thickness(0, scalar*offset, 0, -scalar*offset),
                KeyTime = TimeSpan.FromSeconds(scalar*seconds),
            });
        }   

        //slideAnimation.Duration = TimeSpan.FromSeconds(seconds);

        // Set the target and target property
        Storyboard.SetTarget(slideAnimation, element);
        Storyboard.SetTargetProperty(slideAnimation, "(FrameworkElement.Margin)");

        // Add the animation to the storyboard
        storyboard.Children.Add(slideAnimation);
    }

它有效,看起来不错,但这就是我问这个问题的原因:我不知道它是否正确。我的猜测是,有一种比手动定义 100 个点并使用此动画将对象移动到每个点更好的方法来滑动对象。

【问题讨论】:

    标签: c# xaml animation uwp slide


    【解决方案1】:

    这可行,但不是偏移元素的理想方式。为什么?因为当你真的只需要 一个 DoubleAnimation时,你正在创建两个许多 DiscreteObjectKeyFrames。

    您几乎不应该为元素的Margin 设置动画。要更改其位置,更好的方法是为其变换 (RenderTransform) 的平移值 (即 TranslateX/TranslateY) 设置动画。

    在变换中对任何东西进行动画处理都是有效的。他们脱离了 UI 线程。传统上,它们运行在一个称为 Compositor 线程的特殊线程中(我认为),但自从 Creators Update 以来,它们已经变得更加高效,根据Windows UI team -

    当您在 XAML 中使用情节提要和过渡动画时,您 在引擎盖下使用合成。动画以每帧 60 帧运行 第二个!

    以下是使用这种技术的示例

    public static void Slide(this UIElement target, Orientation orientation, double? from, double to, int duration = 400, int startTime = 0, EasingFunctionBase easing = null)
    {
        if (easing == null)
        {
            easing = new ExponentialEase();
        }
    
        var transform = target.RenderTransform as CompositeTransform;
        if (transform == null)
        {
            transform = new CompositeTransform();
            target.RenderTransform = transform;
        }
        target.RenderTransformOrigin = new Point(0.5, 0.5);
    
        var db = new DoubleAnimation
        {
            To = to,
            From = from,
            EasingFunction = easing,
            Duration = TimeSpan.FromMilliseconds(duration)
        };
        Storyboard.SetTarget(db, target);
        var axis = orientation == Orientation.Horizontal ? "X" : "Y";
        Storyboard.SetTargetProperty(db, $"(UIElement.RenderTransform).(CompositeTransform.Translate{axis})");
    
        var sb = new Storyboard
        {
            BeginTime = TimeSpan.FromMilliseconds(startTime)
        };
    
        sb.Children.Add(db);
        sb.Begin();
    }
    

    请注意,尽管这种方法具有更高的性能,但 UWP 中的动画支持更加强大,这要归功于新的 Composition API。但是合成中的偏移动画可能有点tricky

    但是,UWP 社区工具包 非常出色地封装了一些有用的动画,例如 BlurOffset 等。请随时查看 them

    【讨论】:

      猜你喜欢
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多