泥庭

2013年5月19日

マルチタッチで拡大縮小・回転・移動

Filed under: .NET, ストアアプリ, Windows8 — タグ: , , , — yone64 @ 4:40 午後

マルチタッチの醍醐味はやっぱり拡大縮小・回転ですよね。
これはManipulationDeltaイベントをハンドルすることで実現することができます。

まず、XAML上で動かしたい対象オブジェクトにCompositeTransformを設定します。

<Rectangle Fill="#FF53F030" HorizontalAlignment="Left" Height="100" Margin="940,188,0,0" Stroke="Black" VerticalAlignment="Top" Width="100" 
           ManipulationMode="All" ManipulationDelta="Rectangle_ManipulationDelta">
    <Rectangle.RenderTransform>
        <CompositeTransform/>
    </Rectangle.RenderTransform>
</Rectangle>

ManipulationDeltaイベントでは、移動差分・拡大縮小差分・回転差分が取得できるので、これをCompositeTransformに設定します。

private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var transform = ((UIElement)sender).RenderTransform as CompositeTransform;

    transform.TranslateX += e.Delta.Translation.X;
    transform.TranslateY += e.Delta.Translation.Y;

    transform.ScaleX *= e.Delta.Scale;
    transform.ScaleY *= e.Delta.Scale;

    transform.Rotation += e.Delta.Rotation;
}

簡単ですね。でも少し操作してみるとわかりますが、拡大縮小および回転の起点が左上で固定されています。これを変更するためには、XAML上でRenderTransformOriginを設定します。”0.5,0.5”を設定すると起点がRectangleの中心になります。

<Rectangle Fill="#FF53F030" HorizontalAlignment="Left" Height="100" Margin="940,188,0,0" Stroke="Black" VerticalAlignment="Top" Width="100" 
           ManipulationMode="All" ManipulationDelta="Rectangle_ManipulationDelta" RenderTransformOrigin="0.5,0.5">
    <Rectangle.RenderTransform>
        <CompositeTransform/>
    </Rectangle.RenderTransform>
</Rectangle>

これの起点をタッチごとに変更するためには、下記通りManipulationDeltaイベントでCompositeTransformのCenterXおよびCenterYを設定するとよいのですが、ことはそんなに単純ではなく…。

private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var transform = ((UIElement)sender).RenderTransform as CompositeTransform;

    transform.CenterX = e.Position.X;
    transform.CenterY = e.Position.Y;

    transform.TranslateX += e.Delta.Translation.X;
    transform.TranslateY += e.Delta.Translation.Y;

    transform.ScaleX *= e.Delta.Scale;
    transform.ScaleY *= e.Delta.Scale;

    transform.Rotation += e.Delta.Rotation;
}

この状態で実行すると、拡大縮小・回転時にRectangleがワープします。残念。

WordPress.com Blog.