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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
<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 で指定できるので汎用的に使えます。

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 イベントで拾えるので、ラムダ式で設定しておくとコードが簡単になるかと。移動用のコントロールを消すとか、元の位置に戻すとかを、

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

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

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