如何检测动画何时停止并更新属性? [英] How to I detect when an animation is stopped and properties updated?

查看:15
本文介绍了如何检测动画何时停止并更新属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在视觉层创建并启动动画,我可以使用 StopAnimation 停止动画.但是当我这样做时,似乎需要一段时间才能停止动画并使用最新值更新属性.有办法解决吗?在下面的代码中,我等待了 10 毫秒,但这只是有时有效.

If I create and start an animation in the visual layer, I could use StopAnimation to stop the animation. But when I do that it seems that it takes a while before the animation is stopped and the properties are updated with the latest values. Is there some way around that? In the code below, I wait 10 milliseconds but that only works sometimes.

public sealed partial class MainPage : Page
{
    SpriteVisual MyVisual;

    public MainPage()
    {
        this.InitializeComponent();

        PointerReleased += MainPage_PointerReleased;
    }


    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

        MyVisual = compositor.CreateSpriteVisual();

        MyVisual.Size = new Vector2(80, 80);
        MyVisual.Offset = new Vector3(50, 50, 0);
        MyVisual.Brush = compositor.CreateColorBrush(Colors.Green);

        ElementCompositionPreview.SetElementChildVisual(this, MyVisual);

        var animation = compositor.CreateVector3KeyFrameAnimation();
        animation.InsertKeyFrame(1, new Vector3(300, 50, 0));
        animation.Duration = TimeSpan.FromSeconds(3);
        animation.IterationBehavior = AnimationIterationBehavior.Forever;

        MyVisual.StartAnimation(nameof(MyVisual.Offset), animation);
    }

    private async void MainPage_PointerReleased(object sender, PointerRoutedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Position when animation running: " + MyVisual.Offset);

        MyVisual.StopAnimation(nameof(MyVisual.Offset));

        await Task.Delay(10);

        System.Diagnostics.Debug.WriteLine("Position when animation stopped: " + MyVisual.Offset);
    }
}

推荐答案

您可以使用 CompositionScopedBatch 来解决这个问题.需要注意的一件事是 如果您有无限次迭代(我不知道为什么),则会立即触发 Completed 事件.这是一个示例:

You could use CompositionScopedBatch to solve this. One thing to notice is that the Completed event is triggered immediately if you have infinite number of iterations (I have no idea why). Here is a sample:

public sealed partial class MainPage : Page
{
    SpriteVisual MyVisual;
    CompositionScopedBatch ScopedBatch;

    public MainPage()
    {
        this.InitializeComponent();

        PointerReleased += MainPage_PointerReleased;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

        MyVisual = compositor.CreateSpriteVisual();

        MyVisual.Size = new Vector2(80, 80);
        MyVisual.Offset = new Vector3(50, 50, 0);
        MyVisual.Brush = compositor.CreateColorBrush(Colors.Green);

        ElementCompositionPreview.SetElementChildVisual(this, MyVisual);

        ScopedBatch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation);

        var animation = compositor.CreateVector3KeyFrameAnimation();
        animation.InsertKeyFrame(1, new Vector3(300, 50, 0));
        animation.Duration = TimeSpan.FromSeconds(3);
        // animation.IterationBehavior = AnimationIterationBehavior.Forever;
        // CompositionScopedBatch.Completed is triggered immediately if Infinite is used.
        // Use many iterations instead.
        animation.IterationBehavior = AnimationIterationBehavior.Count;
        animation.IterationCount = 1000000;

        MyVisual.StartAnimation(nameof(MyVisual.Offset), animation);

        ScopedBatch.Completed += CompositionScopedBatch_Completed;

        ScopedBatch.End();
    }

    private void CompositionScopedBatch_Completed(object sender, CompositionBatchCompletedEventArgs args)
    {
        System.Diagnostics.Debug.WriteLine("Position when batch completed: " + MyVisual.Offset);
    }

    private void MainPage_PointerReleased(object sender, PointerRoutedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Position when animation running: " + MyVisual.Offset);

        MyVisual.StopAnimation(nameof(MyVisual.Offset));
    }
}

这篇关于如何检测动画何时停止并更新属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆