UWP wincomposition:为多个图像的偏移设置动画

时间:2017-07-16 13:44:52

标签: c# animation uwp windows-10-universal windows-composition-api

我尝试在一个网格控件中设置多个(不同大小)图像的动画,但只有最大的一个是动画的。目标属性是“Offset.x”。

        var container = new Grid();
        var compositor = ElementCompositionPreview.GetElementVisual(container).Compositor;
        var containerVisual = compositor.CreateContainerVisual();

        // ------
        // CLOUDS
        // ------
        var cloudImage1 = CreateCloudImage(60);
        var cloudVisual1 = ElementCompositionPreview.GetElementVisual(cloudImage1);

        var cloudImage2 = CreateCloudImage(70);
        var cloudVisual2 = ElementCompositionPreview.GetElementVisual(cloudImage2);

        var cloudImage3 = CreateCloudImage(50);
        var cloudVisual3 = ElementCompositionPreview.GetElementVisual(cloudImage3);

        container.Children.Add(cloudImage1);
        container.Children.Add(cloudImage2);
        container.Children.Add(cloudImage3);

        containerVisual.Children.InsertAtTop(cloudVisual1);
        containerVisual.Children.InsertAtTop(cloudVisual2);
        containerVisual.Children.InsertAtTop(cloudVisual3);

        // ----------
        // ANIMATIONS
        // ----------
        var offsetAnimation = CreateOffsetAnimation(compositor, 50, 6);
        cloudVisual1.StartAnimation("Offset.x", offsetAnimation);

        offsetAnimation.InsertKeyFrame(1f, -60);
        cloudVisual2.StartAnimation("Offset.x", offsetAnimation); // doesn't work

        ElementCompositionPreview.SetElementChildVisual(container, containerVisual);

        return container;

助手方法:

static ScalarKeyFrameAnimation CreateOffsetAnimation(Compositor compositor, float endKeyFrame, double duration) {
        var animation = compositor.CreateScalarKeyFrameAnimation();
        animation.InsertKeyFrame(0f, 0);
        animation.InsertKeyFrame(1f, endKeyFrame);
        animation.IterationBehavior = AnimationIterationBehavior.Forever;
        animation.Direction = AnimationDirection.Alternate;
        animation.Duration = TimeSpan.FromSeconds(duration);

        return animation;
}

static Image CreateCloudImage(double size) {
       var cloudBitmapImage = new BitmapImage(new Uri("ms-appx:///Assets/Icons/cloudy.png"));
       var cloudImageControl = new Image() {
            Source = cloudBitmapImage,
            Height = size,
            Width = size,
       };

       return cloudImageControl;
}

请注意,如果我将第二张图像设为最大图像,则会成为动画的图像。

关于如何解决这个问题的任何想法?

提前致谢。

1 个答案:

答案 0 :(得分:2)

简答:使用Canvas控件来保存图片。

完整答案:我找到了解决方案:罪魁祸首是使用Grid控件作为托管我的图像的容器。我认为不知何故(可能是由于其父级的中心水平对齐设置 - 在代码中显示不可见)Grid容器正在为我的图像添加边距,这导致了奇怪的行为,如问题中所述。

为了解决这个问题,我添加了一个Canvas控件来保存我的图像,并将此Canvas添加为Grid容器的子项。

        var container = new Grid();
        var compositor = ElementCompositionPreview.GetElementVisual(container).Compositor;
        var containerVisual = compositor.CreateContainerVisual();

        var canvas = new Canvas();

        // ------
        // CLOUDS
        // ------
        var cloudImage1 = CreateCloudImage(60);
        var cloudVisual1 = ElementCompositionPreview.GetElementVisual(cloudImage1);

        var cloudImage2 = CreateCloudImage(70);
        var cloudVisual2 = ElementCompositionPreview.GetElementVisual(cloudImage2);

        var cloudImage3 = CreateCloudImage(50);
        var cloudVisual3 = ElementCompositionPreview.GetElementVisual(cloudImage3);

        canvas.Children.Add(cloudImage1);
        canvas.Children.Add(cloudImage2);
        canvas.Children.Add(cloudImage3);

        containerVisual.Children.InsertAtTop(cloudVisual1);
        containerVisual.Children.InsertAtTop(cloudVisual2);
        containerVisual.Children.InsertAtTop(cloudVisual3);

        // ----------
        // ANIMATIONS
        // ----------
        var offsetAnimation = CreateOffsetAnimation(compositor, 50, 6);
        cloudVisual1.StartAnimation("Offset.x", offsetAnimation);

        offsetAnimation.InsertKeyFrame(1f, -60);
        cloudVisual2.StartAnimation("Offset.x", offsetAnimation); // work

        offsetAnimation.InsertKeyFrame(1f, 100);
        cloudVisual3.StartAnimation("Offset.x", offsetAnimation); // work

        ElementCompositionPreview.SetElementChildVisual(canvas, containerVisual);

        container.Children.Add(canvas);
        return container;

(用Canvas容器替换Grid容器也应该有效。)