如何使动画改变背景图像?

时间:2019-08-08 15:26:14

标签: c# xaml uwp

我正在使用UWP开发Microsoft Store App,并且正在使用XAML和C#。 我想用不透明动画随机更改背景图像。

我的代码在下面。

此函数以Task.Run(InitializeWorks);

执行
    private async void InitializeWorks()
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
        {
            BackgroundImage.Opacity = 0;
            try
            {
                while (true)
                {
                    var backgroundImageFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(@"Assets\BackgroundImages");
                    var backgroundImageFiles = await backgroundImageFolder.GetFilesAsync();
                    BackgroundImage.Source = new BitmapImage(new Uri(backgroundImageFiles[new Random().Next(0, backgroundImageFiles.Count)].Path));
                    for (double i = BackgroundImage.Opacity; i <= 0.1; i += 0.001)
                    {
                        BackgroundImage.Opacity = i;
                        await Task.Delay(10);
                    }
                    await Task.Delay(5000);
                    for (double i = BackgroundImage.Opacity; i >= 0; i -= 0.001)
                    {
                        BackgroundImage.Opacity = i;
                        await Task.Delay(10);
                    }
                }

            }
            catch (Exception e)
            {
                //
            }

        });

    }
  1. 此代码的性能如何?给您带来不便 这个异步任务?会发生任何错误吗?
  2. 如何使用XAML制作变化的动画?

3 个答案:

答案 0 :(得分:0)

您不能在XAML中调用GetFilesAsyncwhile,但我建议您用DispatcherTimer替换Tick循环,该循环定期更改背景。

{{1}}事件将在UI线程上引发,这意味着可以安全地在事件处理程序中访问UI元素。异步方法不会阻塞。

答案 1 :(得分:0)

您可以在XAML中设置以下动画:

<Page.Resources>
<Storyboard x:Name="MyStoryboard">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="BackgroundImage">​
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>​
                <EasingDoubleKeyFrame KeyTime="0:0:3" Value="0.1"/>​
                <EasingDoubleKeyFrame KeyTime="0:0:6" Value="0"/>​
            </DoubleAnimationUsingKeyFrames>​
        </Storyboard>​
</Page.Resources>

隐藏代码:

您可以使用 StoryBoard.Begin 开始不透明度动画,并且该动画具有 Completed 事件。您可以订阅该动画来收听是否动画完成。动画完成后,您可以调用 InitializeWorks()方法再次更改BackgroundImage。这种书写方式将替换您的 While 方法。

private async void InitializeWorks()
        {​
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>​
            {​
                BackgroundImage.Opacity = 0;​
                try​
                {​
                   ​
                    var backgroundImageFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(@"Assets\BackgroundImages");​
                    var backgroundImageFiles = await backgroundImageFolder.GetFilesAsync();​
                    BackgroundImage.Source = new BitmapImage(new Uri(backgroundImageFiles[new Random().Next(0, backgroundImageFiles.Count)].Path));​
                    MyStoryboard.Begin();​
                    MyStoryboard.Completed += MyStoryboard_Completed;​
                }​
                catch (Exception e)​
                {​
                    //​
                }​
​
            });​
​
        }

private void MyStoryboard_Completed(object sender, object e)
        {​
            InitializeWorks();​
        }

答案 2 :(得分:0)

我通过@faywang @ mm8找到了解决方案

带有Storyboard的XML动画;

    <Storyboard x:Name="BackgroundImageStoryboardIncrease">
        <DoubleAnimation
            Storyboard.TargetName="BackgroundImage"
            Storyboard.TargetProperty="Opacity"
            From="0"
            To="0.15"
            Duration="0:0:2" />
    </Storyboard>
    <Storyboard x:Name="BackgroundImageStoryboardDecrease">
        <DoubleAnimation
            Storyboard.TargetName="BackgroundImage"
            Storyboard.TargetProperty="Opacity"
            From="0.15"
            To="0"
            Duration="0:0:2" />
    </Storyboard>

C#更改事件并停留10秒钟:

    private async void InitializeFrontWorks()
    {
        // Animations
        DispatcherTimer dispatcherTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(10)
        };
        var backgroundImageFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(@"Assets\BackgroundImages");
        var backgroundImageFiles = await backgroundImageFolder.GetFilesAsync();
        AnimationBackgroundImage(backgroundImageFiles);
        dispatcherTimer.Tick += delegate
        {
            AnimationBackgroundImage(backgroundImageFiles);
        };
        dispatcherTimer.Start();
    }
    private void AnimationBackgroundImage(IReadOnlyList<StorageFile> backgroundImageFiles)
    {
        BackgroundImageStoryboardDecrease.Begin();
        BackgroundImageStoryboardDecrease.Completed += delegate
        {
            BackgroundImage.Source = new BitmapImage(new Uri(backgroundImageFiles[new Random().Next(0, backgroundImageFiles.Count)].Path));
            BackgroundImageStoryboardIncrease.Begin();
        };
    }
相关问题