1

複数の(異なるサイズの)画像を1つのグリッドコントロールでアニメーションしようとしましたが、最大のものだけがアニメーション化されます。対象プロパティは "Offset.x"です。UWP wincomposition:複数の画像のオフセットをアニメ化する

 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; 
} 

注私は第二の画像の最大を作るならば、それがアニメ化されたものになるという。

これを解決する方法はありますか?

ありがとうございます。

答えて

2

短い回答:画像を保持するためにキャンバスコントロールを使用します。

完全回答:解決策が見つかりました:犯人は、グリッドコントロールを画像をホストするためのコンテナとして使用していました。私は何とかして(おそらく、その親に設定された中央の水平方向の整列のために、コード内には表示されませんでした)、グリッドコンテナは画像にマージンを追加していました。

これを解決するために、画像を保持する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コンテナに置き換えることもできます)。

+2

これは実際にグリッドが原因です。その理由は[こちら](https://github.com/Microsoft/WindowsUIDevLabs/wiki/XAML-Composition-Interop-Behavior-Changes)で説明されています。キャンバスを使用せずに各画像を枠線でラップすることができます。クリエイターの更新では、オフセットの代わりに翻訳プロパティをアニメートできます。 'StartTranslationAnimation'メソッドを[ここ](https://github.com/JustinXinLiu/Continuity/blob/master/Continuity/Extensions/CompositionExtensions.Translation.cs)からチェックしてください。 –

+1

ありがとう!私はこれを調べるつもりです:) –

関連する問題