Pinch to Zoom

1 article

Pinch to Zoom avec Windows et Windows Phone 8.1

Comment rendre une image zoomable?

Pour l’application Infografx, j’ai eu besoin de gérer le zoom d’un graphique à travers un « pinch to zoom »

Zoom-Gesture

 

Lors de l’utilisation d’une image, l’utilisateur doit pouvoir zoomer et se déplacer dans le Zoom.

Mon premier réflex a été de coder l’utilisation de se zoom et du scale à partir des évenements de manipulation. Et puis comme j’étais dans un modèle M-V-VM j’ai même utilisé un behavior pour rendre le code plus propre.

Tout celà pour rien, car il existe une manière bien plus simple et bien plus efficace…

Avant

Avant, il fallait coder les gestes de l’utilisateur intervenant sur l’image.

Voici un exemple de code qui fait intervenir 2 évènements sur le contrôle ManipulationStart et ManipulationDelta.

    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;
    }

Le code est assez long, le résultat n’est pas parfait car un peu rigide (pas de gestion de l’inertie) et pas facile à insérer dans un modèle M-V-VM.

Il existe un moyen pourtant bien plus simple.

Le ScrollViewer

Avec Windows 8 et les projets Windows Phone 8.1 (non Silverlight), le scrollviewer est enrichi d’un Zoom.

En Initialisant la propriété ZoomMode avec « Enabled », vous bénéficiez d’un Pinch To Zoom sur n’importe quel contenu du ScrollViewer

D’autres propriétés permettent également de paramétrer votre zoom :

  • MinZoomFactor : Pour fixer le zoom minimum (exemple 0.25)
  • MaxZoomFactor : Pour fixer le zoom maximum (exemple 3.0)
  • IsZoomInertiaEnabled : Pour gérer l’inertie du zoom (exemple false)

Ce qui donne en XAML

 <ScrollViewer Width="Auto" Height="Auto" VerticalScrollBarVisibility="Visible"
                          HorizontalScrollBarVisibility="Visible" Margin="4"
                          ZoomMode="Enabled"                           
                          MinZoomFactor="0.25"
                          MaxZoomFactor="3.0"
                          IsZoomInertiaEnabled="False"
                          >
                <Grid VerticalAlignment="Top" HorizontalAlignment="Left"
                       >
...

 

Et voilà! En quelques lignes de code XAML le tour est joué. vous avez un zoom parfait, sans code à maintenir et 100% M-V-VM.