我对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个点,并使用此动画将对象移动到每个点。
答案 0 :(得分:1)
这可行,但不是偏移元素的理想方式。为什么?因为当你真正需要一个 DiscreteObjectKeyFrame
时,你创建了两个DoubleAnimation
。
您几乎不应该为元素的Margin
设置动画。要改变其位置,更好的方法是为其变换(TranslateX
)的转换值(即TranslateY
/ RenderTransform
)设置动画。
在变换中动画任何内容都是有效的。它们不在UI线程中。传统上,它们运行在一个名为 Compositor 线程的特殊线程中(我认为),但自从 Creators Update 以来,它们根据{{3}变得更加高效。 } -
当你在XAML中使用Storyboard和Transition动画时,你就是 使用引擎盖下的组合物。动画以每帧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();
}
请注意,由于新的Composition API,在UWP中有更强大的动画支持。但是,合成中的偏移动画可能有点Windows UI team。
然而, UWP社区Tookit 在包装Blur
,Offset
等有用的动画方面做得非常出色。请随时查看tricky