UWP:如何为 RenderTranform 设置动画并使其在之后保持可用?
UWP: How to animate a RenderTranform and keep it usable after that?
我有一个非常简单的项目,我需要为元素的 RenderTransform 设置动画,然后进一步操作此类变换。
请在此处查找 MVCE 作为参考:https://github.com/cghersi/UWPExamples/tree/master/RenderTransformAnimation。
场景如下:有一个 ScrollViewer m_scrollView
,有一个 Canvas
内容 m_zoomView
。
为了这个例子,我们还有一个 CompositeTransform m_zoomViewTransform = m_zoomView.RenderTransform
.
我使用以下方法来操作 RenderTransform,有或没有动画:
private void SetEffectiveOffsetOfScrollView(Point newOffset, bool isAnimated)
{
if (isAnimated)
{
TimeSpan dur = TimeSpan.FromSeconds(0.2);
Storyboard sb = new Storyboard { Duration = dur };
DoubleAnimation animationX = new DoubleAnimation
{
To = newOffset.X,
Duration = dur,
AutoReverse = false
};
DoubleAnimation animationY = new DoubleAnimation
{
To = newOffset.Y,
Duration = dur,
AutoReverse = false
};
sb.Children.Add(animationX);
sb.Children.Add(animationY);
Storyboard.SetTarget(animationX, m_zoomViewTransform);
Storyboard.SetTarget(animationY, m_zoomViewTransform);
Storyboard.SetTargetProperty(animationX, "CompositeTransform.TranslateX");
Storyboard.SetTargetProperty(animationY, "CompositeTransform.TranslateY");
sb.Begin();
sb.Completed += (sender, o) =>
{
m_zoomViewTransform.TranslateX = newOffset.X;
m_zoomViewTransform.TranslateY = newOffset.Y;
};
}
else
{
m_zoomViewTransform.TranslateX = newOffset.X;
m_zoomViewTransform.TranslateY = newOffset.Y;
}
}
现在,如果我将 SetEffectiveOffsetOfScrollView()
与 isAnimated = true
一起使用,我将无法再更改 RenderTransform
,或者至少我看不到 [=] 的任何更新39=] 了。
在 MVCE 中,我添加了一个使用 isAnimated = true
调用 SetEffectiveOffsetOfScrollView()
方法的按钮,并且我添加了一个操作事件来平移 m_zoomView Canvas
:只要我点击按钮,我无法再平移 Canvas
.
如何设置动画转换,在此操作后仍然能够看到 UI 的更新,使用 SetEffectiveOffsetOfScrollView()
和 animate=false
?
这是由于依赖性 属性 值优先,如下所述:
https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/dependency-properties-overview#dependency-property-value-precedence
在此重现中,由于 DoubleAnimations 上的默认 FillBehavior=HoldEnd,故事板仍然处于活动状态。由于这些动画仍然存在,因此使用动画值,即使在 isAnimated=false 情况下设置了新的本地值。
最简单的解决方法是在将新的局部值设置为保留后,在 Storyboard 的 Completed 处理程序中调用 sb.Stop()。这将停止动画,删除它们持有的动画值,并允许使用本地值。
我有一个非常简单的项目,我需要为元素的 RenderTransform 设置动画,然后进一步操作此类变换。
请在此处查找 MVCE 作为参考:https://github.com/cghersi/UWPExamples/tree/master/RenderTransformAnimation。
场景如下:有一个 ScrollViewer m_scrollView
,有一个 Canvas
内容 m_zoomView
。
为了这个例子,我们还有一个 CompositeTransform m_zoomViewTransform = m_zoomView.RenderTransform
.
我使用以下方法来操作 RenderTransform,有或没有动画:
private void SetEffectiveOffsetOfScrollView(Point newOffset, bool isAnimated)
{
if (isAnimated)
{
TimeSpan dur = TimeSpan.FromSeconds(0.2);
Storyboard sb = new Storyboard { Duration = dur };
DoubleAnimation animationX = new DoubleAnimation
{
To = newOffset.X,
Duration = dur,
AutoReverse = false
};
DoubleAnimation animationY = new DoubleAnimation
{
To = newOffset.Y,
Duration = dur,
AutoReverse = false
};
sb.Children.Add(animationX);
sb.Children.Add(animationY);
Storyboard.SetTarget(animationX, m_zoomViewTransform);
Storyboard.SetTarget(animationY, m_zoomViewTransform);
Storyboard.SetTargetProperty(animationX, "CompositeTransform.TranslateX");
Storyboard.SetTargetProperty(animationY, "CompositeTransform.TranslateY");
sb.Begin();
sb.Completed += (sender, o) =>
{
m_zoomViewTransform.TranslateX = newOffset.X;
m_zoomViewTransform.TranslateY = newOffset.Y;
};
}
else
{
m_zoomViewTransform.TranslateX = newOffset.X;
m_zoomViewTransform.TranslateY = newOffset.Y;
}
}
现在,如果我将 SetEffectiveOffsetOfScrollView()
与 isAnimated = true
一起使用,我将无法再更改 RenderTransform
,或者至少我看不到 [=] 的任何更新39=] 了。
在 MVCE 中,我添加了一个使用 isAnimated = true
调用 SetEffectiveOffsetOfScrollView()
方法的按钮,并且我添加了一个操作事件来平移 m_zoomView Canvas
:只要我点击按钮,我无法再平移 Canvas
.
如何设置动画转换,在此操作后仍然能够看到 UI 的更新,使用 SetEffectiveOffsetOfScrollView()
和 animate=false
?
这是由于依赖性 属性 值优先,如下所述: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/dependency-properties-overview#dependency-property-value-precedence
在此重现中,由于 DoubleAnimations 上的默认 FillBehavior=HoldEnd,故事板仍然处于活动状态。由于这些动画仍然存在,因此使用动画值,即使在 isAnimated=false 情况下设置了新的本地值。
最简单的解决方法是在将新的局部值设置为保留后,在 Storyboard 的 Completed 处理程序中调用 sb.Stop()。这将停止动画,删除它们持有的动画值,并允许使用本地值。