[WinRT] 指定位置からコントロールをアニメーションさせる

[WinRT] Gridに貼り付けたコントロールの絶対座標を取得する | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/4062

の続きです。この絶対座標を使ってアニメーションさせれば ok っだね、ってことで先に絶対座標を計算いたのですが、実はアニメーション自体は「相対座標」になるので、この手の Margin のややこしい計算は必要がなかったんですよね~、というオチです。

条件としては、適当に移動コントロールを用意しておいて、適当な開始位置から適当な終了位置までにアニメーションします。
アニメーション自体は、Blend を使って大体の位置で作成しておきます。「大体」でよいのは、開始位置と終了位置はプログラムのほうで制御するためです。

<Page.Resources>
	<Storyboard x:Name="sbMove1">
		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="pict1">
			<EasingDoubleKeyFrame x:Name="startPosX" KeyTime="0" Value="405.97"/>
			<EasingDoubleKeyFrame x:Name="endPosX" KeyTime="0:0:3" Value="441.791"/>
		</DoubleAnimationUsingKeyFrames>
		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="pict1">
			<EasingDoubleKeyFrame x:Name="startPosY" KeyTime="0" Value="277.612"/>
			<EasingDoubleKeyFrame x:Name="endPosY"  KeyTime="0:0:3" Value="-11.941"/>
		</DoubleAnimationUsingKeyFrames>
	</Storyboard>
</Page.Resources>

あらかじめ作った storyboard に対して変更部分に名前をつけていきます。開始位置(startPosX,startPosY) と終了位置(endPosX,endPosY) だけで ok です。アニメーションする時間を変更したい場合は、endPosX.KeyTime, endPosY.KeyTime で指定できるので汎用的に使えます。

■アニメーションを開始する

これを使ってアニメーションさせるのが次のコードです。

private void Button3Click(object sender, RoutedEventArgs e)
{
	// 移動対象の絶対座標
	var pt1 = _pt1;
	// 開始位置の絶対座標
	var pt2 = pict2.TransformToVisual(null).TransformPoint(new Point(0, 0));
	// 終了位置の絶対座標
	var pt3 = pict3.TransformToVisual(null).TransformPoint(new Point(0, 0));
	// 開始、終了位置を相対座標で設定
	startPosX.Value = pt2.X - pt1.X;
	startPosY.Value = pt2.Y - pt1.Y;
	endPosX.Value = pt3.X - pt1.X;
	endPosY.Value = pt3.Y - pt1.Y;
	// アニメーション開始
	sbMove1.Begin();
	sbMove1.Completed += (_, __) => { ; };
}

startPosX.Value に設定するのは、相対座標なので、pt2.X – pt1.X になります。元の pt1 を取っておかないとダメなのがちょっとダサいですが、移動用のコントロールの座標を(0,0)にして左上にしておけば、pt1 の値はいりません。

アニメーションの終了は、Completed イベントで拾えるので、ラムダ式で設定しておくとコードが簡単になるかと。移動用のコントロールを消すとか、元の位置に戻すとかを、

	sbMove1.Completed += (_, __) =>
	{
		sbMove1.Stop();
		grid1.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
	};

のようにしておくとよいかと。

カテゴリー: C#, WinRT パーマリンク