Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smooth pinch-zooming and panning on Windows Phone 8

I've managed to implement pinch zooming and panning by hooking up to the ManipulationDelta and ManipulationStarted events (on an image control):

    private void image_OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
        var transform = (CompositeTransform)image.RenderTransform;

        // pan
        transform.TranslateX = _translationX + e.CumulativeManipulation.Translation.X;
        transform.TranslateY = _translationY + e.CumulativeManipulation.Translation.Y;

        // zoom
        if (e.PinchManipulation != null)
        {
            transform.CenterX = e.PinchManipulation.Original.Center.X;
            transform.CenterY = e.PinchManipulation.Original.Center.Y;

            transform.ScaleX = _scaleX * e.PinchManipulation.CumulativeScale;
            transform.ScaleY = _scaleY * e.PinchManipulation.CumulativeScale;
        }
    }

    private void image_OnManipulationStarted(object sender, ManipulationStartedEventArgs e)
    {
        // the user has started manipulating the screen, set starting points
        var transform = (CompositeTransform)image.RenderTransform;
        _scaleX = transform.ScaleX;
        _scaleY = transform.ScaleY;
        _translationX = transform.TranslateX;
        _translationY = transform.TranslateY;
    }

But the compared to the smoothness of the rest of the windows phone UI it feels very placid and stiff. There is no inertia in the movement.

Is there a way to make the movements more smooth? Is using animations and storyboards a way to go about it? I've tried using ScrollView for at least getting smooth panning but then the ManipulationDelta events are not firing correctly.

like image 242
Pking Avatar asked Feb 01 '13 18:02

Pking


3 Answers

I wanted to get this right from a mathematical point of view. The result is something similar in correctness to Telerik's PanAndZoomImage. If you aren't interested, jump straight to this gist (It works with WP7.1+). You'll need to reference System.Windows.Interactivity and the Windows Phone toolkit.

Usage:

<Image Source="http://i.imgur.com/ZbKlRzK.jpg">
    <i:Interaction.Behaviors>
        <phoneApp1:PanAndZoomBehavior MaxZoom="10" />
    </i:Interaction.Behaviors>
</Image>

Math

Panning and zooming uses 2 out of 4 transformations of CompositeTransform, namely Translation and Scaling. The key point is understanding how to compose two of those scale+translate transforms. I'll use haskellish notation, because it is less of burden to type and read. Our 'primitives' are

  1. scale s = scale around (s.x,s.y) with factor s.x in x direction and s.y in y direction
  2. translate t = offset all points by t.x in x direction and t.y in y direction

CompositeTransform scales around a center point, which is expressed like

scaleAround c s = translate c . scale s . translate -c

The following rules hold (do the math if you don't believe me, all operators are componentwise):

  1. translate a . translate b = translate (a+b)
  2. scale a . scale b = scale (a*b)
  3. translate t . scale s = scale s . translate (t/s)

A CompositeTransform is like

transform s c t = translate t . scaleAround c s
                = translate (t+c) . scale s . translate -c

When composing two of those transforms, we have to move around primitives until we get to such a form above. Let a and b be those two CompositeTransforms. So we get:

transform' = b . a
           = translate bt . scaleAround bc bs . translate at . scaleAround ac as
           = translate bt . translate bc . scale bs . translate -bc . translate at . translate ac . scale as . translate -ac
           = translate (bt+bc) . scale bs . translate (ac+at-bc) . scale as . translate -ac
           = translate (bt+bc) . translate (ac+at-bc)*bs . scale bs . scale as . translate -ac
           = translate (bt+bc+(ac+at-bc)*bs) . scale (as*bs) . translate -ac
           = translate (bt+bc-ac+(ac+at-bc)*bs) . scaleAround ac (as*bs)
           = translate (bt+at*bs+(bs-1)*(ac-bs)) . scaleAround ac (as*bs)

This is just because I was frustrated with the amount of profound documentation on why certain people do certain things.

For the actual composition code, looko here

like image 163
Sebastian Graf Avatar answered Nov 09 '22 23:11

Sebastian Graf


I know you're talking about 8 and I'll post a link to an article related to 7, but it was very useful when playing around with Windows Phone so here it goes:

https://www.wintellect.com/building-touch-interfaces-for-windows-phones-part-3/

I don't imagine that much has changed since then...

like image 37
Alex Paven Avatar answered Nov 09 '22 23:11

Alex Paven


I know it's a late answer but here's another sample project which could help to resolve this problem http://code.msdn.microsoft.com/wpapps/Smooth-flick-and-zoom-with-7760c7f7

like image 1
Shendor Avatar answered Nov 09 '22 23:11

Shendor