0
votes

I move and scale a rectangle within a canvas element with touch gestures. The code is based on this reference: http://msdn.microsoft.com/en-us/magazine/gg650664.aspx

The XAML code is as follows:

<Canvas Name="canvas" >
    <Rectangle x:Name="rectangle" Fill="Green"  Height="300" Canvas.Left="0" Stroke="Red" Canvas.Top="0" Width="100" StrokeThickness="3" >
        <Rectangle.RenderTransform>
            <TransformGroup>
                <MatrixTransform x:Name="previousTransform" />

                <TransformGroup x:Name="currentTransform">
                    <ScaleTransform x:Name="scaleTransform" />
                    <TranslateTransform x:Name="translateTransform" />
                </TransformGroup>
            </TransformGroup>
        </Rectangle.RenderTransform>

        <toolkit:GestureService.GestureListener>
            <toolkit:GestureListener DragStarted="OnGestureListenerDragStarted"
                             DragDelta="OnGestureListenerDragDelta"
                             DragCompleted="OnGestureListenerDragCompleted"
                             PinchStarted="OnGestureListenerPinchStarted"
                             PinchDelta="OnGestureListenerPinchDelta"
                             PinchCompleted="OnGestureListenerPinchCompleted" />
        </toolkit:GestureService.GestureListener>
    </Rectangle>
</Canvas>

Dragging:

void OnGestureListenerDragDelta(object sender, DragDeltaGestureEventArgs args)
{
    translateTransform.X += args.HorizontalChange;
    translateTransform.Y += args.VerticalChange;
}

During pinching the scale transform is updated:

void OnGestureListenerPinchDelta(object sender, PinchGestureEventArgs args)
{
    scaleTransform.ScaleX = args.DistanceRatio;
    scaleTransform.ScaleY = args.DistanceRatio;
}

When pinching completes I want to get the "real" size and position of the rectangle within the parent canvas. Therefore I tried to apply the transform to the rectangle boundaries:

void OnGestureListenerPinchCompleted(object sender, PinchGestureEventArgs args)
{
    Rect r = currentTransform.TransformBounds(new Rect(Canvas.GetLeft(rectangle), Canvas.GetTop(rectangle), rectangle.Width, rectangle.Height));
    rectangle.Width = r.Width;
    rectangle.Height = r.Height;
    Canvas.SetLeft(rectangle, r.X);
    Canvas.SetTop(rectangle, r.Y);

    // Reset transforms
    previousTransform.Matrix = new Matrix();
    rectangle.RenderTransformOrigin = new Point(0, 0);

    scaleTransform.ScaleX = scaleTransform.ScaleY = 1;
    scaleTransform.CenterX = scaleTransform.CenterY = 0;

    translateTransform.X = translateTransform.Y = 0;
}

This works fine for translation, but scaling is wrong (the rectangle is scaled but the factor is too big when increasing the scale, and too little when decreasing the scale). How can I get the correct final size of the scaled rectangle?

Regards

1

1 Answers

0
votes

I fixed the problem by ommitting the transformation matrix classes and using the scaling factor and translation values manually.

Nevertheless I would be interested in a solution for using the XAML code above.