質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

3207閲覧

【C#】【WPF】アニメーションのパフォーマンスをあげるには?

OXamarin

総合スコア59

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

2クリップ

投稿2019/07/16 14:41

##悩んでいる点

ハンバーガーメニューをクリックするとメニューの幅が広がり、操作している画面にオーバレイをはる、よくみるスマホアプリのような動きをアニメーションで作りました。

分り辛いですが、左上にハンバーガーメニューを配置しています。
イメージ説明

Gifからも分かる通り、画面サイズが大きい場合と小さい場合とでは明らかに矢印のローテーションが遅いです。
このGifの場合はかなり画面サイズの差が大きいですが、通常開く画面と最大化した状態でもこのGifとほぼ変わらないぐらいの速度差が体感できてしまいます。

このモッサリ感をなくすため、どのようにすればアニメーションのパフォーマンスをあげられるのでしょうか。

##実装
ハンバーガーメニュー押下時に、以下のStoryboardが実行されます。

xaml

1<Visibility x:Key="Visible">Visible</Visibility> 2<Visibility x:Key="Collapsed">Collapsed</Visibility> 3<!-- ハンバーガーメニュー押下時のStoryboard --> 4<Storyboard x:Key="OpenMenu"> 5 <!--メニューを開く--> 6 <DoubleAnimation From="70" To="200" Duration="0:0:0.2" 7 Storyboard.TargetName="SlideMenu" 8 Storyboard.TargetProperty="(StackPanel.Width)"> 9 <DoubleAnimation.EasingFunction> 10 <ExponentialEase Exponent="2" EasingMode="EaseInOut" /> 11 </DoubleAnimation.EasingFunction> 12 </DoubleAnimation> 13 <!--ハンバーガーメニューを非表示--> 14 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonOpenMenu" 15 Storyboard.TargetProperty="Visibility"> 16 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Collapsed}" /> 17 </ObjectAnimationUsingKeyFrames> 18 <!--矢印を表示--> 19 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonCloseMenu" 20 Storyboard.TargetProperty="Visibility"> 21 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Visible}" /> 22 </ObjectAnimationUsingKeyFrames> 23 <!--オーバレイの表示--> 24 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="GridOverlay" 25 Storyboard.TargetProperty="Visibility"> 26 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Visible}" /> 27 </ObjectAnimationUsingKeyFrames> 28 <!--メニューの表示状態を隠し項目に持たせる--> 29 <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ChkOpenedMenu" 30 Storyboard.TargetProperty="IsChecked"> 31 <DiscreteBooleanKeyFrame KeyTime="0" Value="True" /> 32 </BooleanAnimationUsingKeyFrames> 33 <!--オーバレイをフェードインさせる--> 34 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="GridOverlay" 35 Storyboard.TargetProperty="(Grid.Opacity)"> 36 <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 37 <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/> 38 </DoubleAnimationUsingKeyFrames> 39 <!--矢印を回転させる--> 40 <DoubleAnimation Storyboard.TargetName="ButtonCloseMenuRotate" 41 Storyboard.TargetProperty="Angle" 42 From="0" To="180" Duration="0:0:0.2"/> 43</Storyboard>

上記のStoryBoardの説明として、
左側に並んでいる部分がメニュー(x:Name = SlideMenu)で
ハンバーガーメニューのボタン(x:Name = ButtonOpenMenu)を押した際に、ハンバーガーメニューは非表示にして、
代わりに矢印のボタン(x:Name = ButtonCloseMenu)を表示させます。矢印ボタンを180度まで回転させつつ、
オーバレイ(x:Name = GridOverlay)の透過度を0から1まで変更しています。

##実装で気を付けた点
アニメーションのパフォーマンスではZindexとOpacityの変更が最悪だとどこかで書いてありました。
オーバレイのZIndexに関しては、元々0~100までを0.2秒間かけて変化させていましたがその記載を見て、最初からZindex=100で配置しておき、表示・非表示に関してはVisibilityで制御するようにしています。

ただ、Opacityに関してはオーバレイがパッと表示されるとスマホのような動きから逸脱してしまうので残してしまっている状態です。要はシームレスなUI変更さえ実現できればなんでもよいのですが今の知識だとOpacityの値を変更させるぐらいしかわかりません。

##他の情報

C#

1 <!--メニューを開く--> 2 <DoubleAnimation From="70" To="200" Duration="0:0:0.2" 3 Storyboard.TargetName="SlideMenu" 4 Storyboard.TargetProperty="(StackPanel.Width)"> 5 <DoubleAnimation.EasingFunction> 6 <ExponentialEase Exponent="2" EasingMode="EaseInOut" /> 7 </DoubleAnimation.EasingFunction> 8 </DoubleAnimation> 9 <!--オーバレイをフェードインさせる--> 10 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="GridOverlay" 11 Storyboard.TargetProperty="(Grid.Opacity)"> 12 <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 13 <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/> 14 </DoubleAnimationUsingKeyFrames>

上記の二つのアニメーションを消すと最大画面でも違和感のない速度になります。
イメージ説明
これらがボトルネックなのでしょうか…

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

アニメーションによって WrapPanel の Width が連動して変化するため、WrapPanel 内の再配置が頻繁に起きているのが原因だと思います。

下のようにすると、ラップパネルのサイズはアニメーションと無関係になるので、スムーズになると思います。違ったらすみません。

xml

1<Grid> 2 <!-- ColumnDefinition なし --> 3 <WrapPanel Name="mainArea" Margin="20,0,0,0"/> 4 <StackPanel Name="sideMenu" HorizontalArignment="Left" Width="20"/> 5 6</Grid>

投稿2019/07/16 23:03

gaya-K

総合スコア449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

OXamarin

2019/07/17 20:30

ありがとうございます!解決しました! コントロールの重ね方がわからずにいたのですがこのようにすればよかったのですね!! 上記の方法でメニューを閉じる際のアニメーションは画面サイズによらずに早くなりました。 メニューを開く際はOpacityに対するアニメーションをいれてましたが開閉がモッサリしてる方がストレスになるとおもうので消して対応しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問