UWP wincomposition:为多个图像的偏移设置动画
UWP wincomposition: animate multiple images' offset
我尝试在一个网格控件中为多个(不同大小的)图像制作动画,但只有最大的一个是动画的。目标 属性 是 "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;
}
请注意,如果我将第二张图像设为最大,它就会变成动画图像。
知道如何解决这个问题吗?
提前致谢。
简短回答: 使用 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 容器也应该有效)。
我尝试在一个网格控件中为多个(不同大小的)图像制作动画,但只有最大的一个是动画的。目标 属性 是 "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;
}
请注意,如果我将第二张图像设为最大,它就会变成动画图像。
知道如何解决这个问题吗?
提前致谢。
简短回答: 使用 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 容器也应该有效)。