c#中的滑动元素UWP
我对UWP中的动画有疑问。我想在我的应用程序的底部有一个菜单,当点击顶部时,可以滑动(显示)或向下(几乎完全隐藏)。我在之前和之后学习WPF,我知道我可以使用ThicknessAnimation来移动我的控件的边距并使其滑动。不幸的是,在UWP中我不能使用ThicknessAnimations,所以我试图找到另一种方法。我希望这可以用于任意的FrameworkElement(以便能够重用它)。最后,我想出了这个解决方案:c#中的滑动元素UWP
/// <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个点,并使用这个动画将物体移动到每个点。
这个工程,但只是不是偏移元素的理想方式。为什么?因为当你真的只需要一个DoubleAnimation
时,你创建了两个很多的DiscreteObjectKeyFrame
。
你几乎不应该动画元素的Margin
。为了改变它的位置,更好的方法是使其变换(TranslateX
/TranslateY
)的变换值(RenderTransform
)变为动画。
动画变换中的任何内容都是有效的。他们脱离了UI线程。传统上,他们在一个特殊的线程中运行叫做排字线程(我认为),但由于创作者更新以往,他们已经根据Windows UI team变得更高性能 -
当您使用故事板和在XAML中转换动画,你在 下使用了Composition。动画以每秒 秒的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更强大的动画支持,感谢新组成的API。但是Composition中的偏移动画可能有点tricky。
然而,UWP社区的无线工具包做了伟大的工作,包装了一些有用的动画像Blur
,Offset
等随时检查them出来。