Windows Phoneのアニメーション画面の向き

Windows Phoneストアには、一般的に縦向きでのみ動作するアプリケーションがたくさんあることに気付くのは簡単です。 これは、これがWindows Phoneのデフォルトの状態であるという事実に一部起因しています。 標準の電卓はサンプルアプリケーションと見なすことができ、画面を傾ける機能を最大限に活用できます。







縦向きでは、簡単な計算機が得られます。 そして、すでに風景の中-エンジニアリング。







しかし、最も美しいのは、あるモードから別のモードへの移行のアニメーションです。



彼の小さなプロジェクトの開発: TapHintアプリケーションは、プログラムインターフェイスの認識を改善するいくつかのことを実装しました。 何らかの理由で、電話のフリップのアニメーションのような有用なものの重要な実装であるように思えました。 そして、インターネット上で何らかの形でこのトピックに関する情報が見つかりました。 アプリケーション自体は、NDEF形式の標準NFCタグで動作し、それらに情報を書き込み、それに応じてそれらから読み取ります。



ラベルに記録された情報を表示するアプリケーションページの場合、アニメーションフリップのサポートを適用することが決定されました。 結果は次のようになります。



ポートレートおよびランドスケープビュー:











中間状態のアニメーションからのフレーム:











結局のところ、電話を傾けるすべての可能なタイプの処理の実装は非常に面倒です。



XAMLページShowPage.xaml
<phone:PhoneApplicationPage x:Class="Tap_Hint.ShowPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="PortraitOrLandscape" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True" Name="showPage" OrientationChanged="showPage_OrientationChanged"> <phone:PhoneApplicationPage.Projection> <PlaneProjection x:Name="showPageRotation" CenterOfRotationX="0" RotationY="0"/> </phone:PhoneApplicationPage.Projection> <phone:PhoneApplicationPage.Resources> <Storyboard x:Name="showPageStoryboardTo"> <DoubleAnimation From="-55.0" To="0.0" Duration="00:00:00.35" Storyboard.TargetName="showPageRotation" Storyboard.TargetProperty="RotationY"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseIn"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </phone:PhoneApplicationPage.Resources> <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name="LayoutRoot" Background="Transparent"> <!-- VisualStateManager.VisualStateGroups must be defined in main grid --> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="FromPToLR"> <!-- from portrait to landscape right and so on --> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateY"> <DiscreteObjectKeyFrame KeyTime="0" Value="-16"/> </ObjectAnimationUsingKeyFrames> <DoubleAnimation From="190.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateX"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation From="90.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="Rotation"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </VisualState> <VisualState x:Name="FromPToLL"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateY"> <DiscreteObjectKeyFrame KeyTime="0" Value="-16"/> </ObjectAnimationUsingKeyFrames> <DoubleAnimation From="-190.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateX"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation From="-90.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="Rotation"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </VisualState> <VisualState x:Name="FromLRToP"> <Storyboard> <DoubleAnimation From="0.0" To="-190.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateY"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation From="-90.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="Rotation"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </VisualState> <VisualState x:Name="FromLLToP"> <Storyboard> <DoubleAnimation From="0.0" To="-190.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateY"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation From="90.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="Rotation"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </VisualState> <VisualState x:Name="FromLRToLL"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateY"> <DiscreteObjectKeyFrame KeyTime="0" Value="-16"/> </ObjectAnimationUsingKeyFrames> <DoubleAnimation From="-180.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="Rotation"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </VisualState> <VisualState x:Name="FromLLToLR"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="showTransform" Storyboard.TargetProperty="TranslateY"> <DiscreteObjectKeyFrame KeyTime="0" Value="-16"/> </ObjectAnimationUsingKeyFrames> <DoubleAnimation From="180.0" To="0.0" Duration="00:00:00.50" Storyboard.TargetName="showTransform" Storyboard.TargetProperty="Rotation"> <DoubleAnimation.EasingFunction> <CubicEase EasingMode="EaseInOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,0,0,0" Orientation="Horizontal"> <Image Width="32" Height="32" Source="/Tap Hint - logo mini (tr, white).png" Margin="5,0,0,0"/> <TextBlock Canvas.ZIndex="8" Text="{Binding Path=LocalizedResources.AboutPage_ApplicationTitle, Source={StaticResource LocalizedStrings}}" FontSize="22" Margin="5,0,0,0"/> <!--<TextBlock Name="textBlockPlus" Canvas.ZIndex="8" Text="{Binding Path=LocalizedResources.AboutPage_ApplicationTitle_Plus, Source={StaticResource LocalizedStrings}}" FontSize="20" Margin="5,0,0,0" Foreground="#FF4959FF"/>--> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Border x:Name="showBorder" Grid.Row="1" Width="400" Height="300" BorderThickness="5" RenderTransformOrigin="0.5,0.5"> <Border.RenderTransform> <CompositeTransform x:Name="showTransform" Rotation="0" TranslateY="-190" TranslateX="0"/> </Border.RenderTransform> <ScrollViewer x:Name="showScroller" VerticalScrollBarVisibility="Auto"> <TextBlock x:Name="showTextBlock" TextAlignment="Center" TextWrapping="Wrap" ScrollViewer.VerticalScrollBarVisibility="Auto"/> </ScrollViewer> </Border> </Grid> </Grid> </phone:PhoneApplicationPage>
      
      







まず、パラメーターSupportedOrientations = "PortraitOrLandscape"を使用して、アプリケーションページの両方の方向をサポートすることを指定する必要があります。 パラメータOrientation =“ Portrait”は、デフォルトの方向を設定します。 ただし、アニメーションなしでページを前後に倒すだけです。 アニメーションのセットを説明するには、VisualStateManagerを使用する必要があります。 その中で、さまざまな状況で使用したいすべてのVisualState遷移を記述することができます。 各VisualStateでは、ストーリーボードにアニメーションを記述することができます(複数ある場合は、同時に再生します)。



たとえば、ポートレートからランドスケープに切り替えるVisualStateは、x:Name = " FromPToLR "と呼ぶことができます。 携帯電話の右側が下にある場合、「風景右」は風景であることが明確になります。 したがって、1つの縦向きと2つの横向きを取得します。 状況は、ある方向から別の方向への両方向の遷移を記述する必要があるという事実によって悪化します。 そして、明らかではないかもしれないのは、ある風景から別の風景へ、またはその逆への移行です。 合計6つの遷移。



CSページShowPage.xaml.cs
 using System.Linq; using System.Windows; using System.Windows.Navigation; using System.Windows.Media; using Microsoft.Phone.Controls; namespace Tap_Hint { public partial class ShowPage : PhoneApplicationPage { private PageOrientation m_ePageOrientation = PageOrientation.PortraitUp; public ShowPage() { InitializeComponent(); bool isDefaultColor = SettingsStore.get().extractParamBool(SettingsStore.StoringParams.USE_DEFAULT_COLOR.ToString()); showTextBlock.FontSize = SettingsStore.g_FontSizeStep * (SettingsStore.get().extractParamInt(SettingsStore.StoringParams.FONT_SIZE.ToString()) + 1); if (isDefaultColor) { showTextBlock.Foreground = (Brush)Application.Current.Resources["PhoneAccentBrush"]; } else { showTextBlock.Foreground = new SolidColorBrush(Colors.White); } } protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.New) { showPageStoryboardTo.Begin(); if (NavigationContext.QueryString.Values != null && NavigationContext.QueryString.Values.ToArray() != null && NavigationContext.QueryString.Values.ToArray().Length > 0) { if ("tagParam".Equals(NavigationContext.QueryString.Keys.ElementAt(0))) { showTextBlock.Text = NavigationContext.QueryString.Values.ElementAt(0); } if ("isEnc".Equals(NavigationContext.QueryString.Keys.ElementAt(1)) && "true".Equals(NavigationContext.QueryString.Values.ElementAt(1))) { showBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 250, 250, 0)); } else if ("isEnc".Equals(NavigationContext.QueryString.Keys.ElementAt(1)) && "false".Equals(NavigationContext.QueryString.Values.ElementAt(1))) { showBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 20, 230, 30)); } else if ("isEnc".Equals(NavigationContext.QueryString.Keys.ElementAt(1)) && "spec".Equals(NavigationContext.QueryString.Values.ElementAt(1))) {//spec - error or encoded on enother device showBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 240, 30, 30)); } } else { showTextBlock.Text = "no param"; } } } protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { if (e.NavigationMode != NavigationMode.Back) {//leave the page due to long back button or Windows button, stay on the page return; } App.Current.Terminate(); //application exiting } private void showPage_OrientationChanged(object sender, OrientationChangedEventArgs e) { //playback animations on orientation change if (m_ePageOrientation == PageOrientation.PortraitUp && e.Orientation == PageOrientation.LandscapeRight) { VisualStateManager.GoToState(this, "FromPToLR", true); } else if (m_ePageOrientation == PageOrientation.PortraitUp && e.Orientation == PageOrientation.LandscapeLeft) { VisualStateManager.GoToState(this, "FromPToLL", true); } else if (m_ePageOrientation == PageOrientation.LandscapeRight && e.Orientation == PageOrientation.PortraitUp) { VisualStateManager.GoToState(this, "FromLRToP", true); } else if (m_ePageOrientation == PageOrientation.LandscapeLeft && e.Orientation == PageOrientation.PortraitUp) { VisualStateManager.GoToState(this, "FromLLToP", true); } else if (m_ePageOrientation == PageOrientation.LandscapeRight && e.Orientation == PageOrientation.LandscapeLeft) { VisualStateManager.GoToState(this, "FromLRToLL", true); } else if (m_ePageOrientation == PageOrientation.LandscapeLeft && e.Orientation == PageOrientation.LandscapeRight) { VisualStateManager.GoToState(this, "FromLLToLR", true); } //saving current orientation mode if (e.Orientation == PageOrientation.PortraitUp) { m_ePageOrientation = PageOrientation.PortraitUp; } else if (e.Orientation == PageOrientation.LandscapeRight) { VisualStateManager.GoToState(this, "LandscapeState", true); m_ePageOrientation = PageOrientation.LandscapeRight; } else if (e.Orientation == PageOrientation.LandscapeLeft) { m_ePageOrientation = PageOrientation.LandscapeLeft; } } } }
      
      







ページコードでは、方向変更ハンドラーshowPage_OrientationChanged()を使用します。 m_ePageOrientation変数の値を使用して、どの方向がe.Orientationでどの画面方向になったかを分析することにより、目的のアニメーションを適用できます。



これらの便利なデコレーションを作成するのが面倒ではない携帯電話向けのアプリケーションが増えることが望まれます。



All Articles