Dans un précédent article je vous avais expliqué comment lire un QR Code depuis une application .NET MAUI. J’avais aussi mis en ligne un projet d’exemple.
Dans ce projet d’exemple on pouvait modifier le zoom de la caméra via un Slider.
Nous allons maintenant voir comment effectuer la même opération en passant par la reconnaissance d’un geste, le « Pinch Gesture » (pincement) qu’on utilise généralement pour zoomer dans une image.
Ajouter la reconnaissance du geste
Il faut dans un premier temps ajouter la reconnaissance du geste au contrôle CameraView. En .NET MAUI c’est très simple, il suffit d’ajouter à la collection des Gestures du contrôle un PinchGestureRecognizer directement dans le code XAML de la page.
<camera:CameraView
x:Name="CameraView"
Grid.Row="0"
Margin="30,30,30,0"
Loaded="CameraView_Loaded"
BarcodeDetected="CameraView_BarcodeDetected"
ZoomFactor="{Binding Source={x:Reference ZoomSlider}, Path=Value}">
<camera:CameraView.GestureRecognizers>
<TapGestureRecognizer x:Name="CameraViewTapGesture" Tapped="CameraViewTapGesture_Tapped" />
<PinchGestureRecognizer x:Name="CameraViewPinchGesture" PinchUpdated="CameraViewPinchGesture_PinchUpdated" />
</camera:CameraView.GestureRecognizers>
</camera:CameraView>
Dans le code d’origine on reconnaissait déjà le Tap via un TapGestureRecognizer pour forcer une mise au point (autofocus). Il suffit donc j’ajouter le nouveau geste à reconnaître en plus de celui qui est déjà utilisé.
Répondre à l’événement PinchUpdated
Quand le geste Pinch est reconnu, un événement PinchUpdated est généré. Cet événement nous donne toute les informations nécessaires pour calculer l’étendue de l’augmentation ou de la diminution de la valeur de zoom à appliquer (proportionnel à l’écartement des doigts).
Les valeurs fournies par l’événement sont :
double Scale
Point ScaleOrigin
GestureStatus Status
La propriété Status permet de savoir si le geste commence, est en cours ou se termine (très important dans notre cas). La propriété Scale permet de connaître l’étendue du geste de pincement (écartement des doigts). Quant à la propriété ScaleOrigin, elle permet de connaître la position du point pris en compte pour effectuer le calcul de Scale (on ne va pas s’en servir pour notre besoin).
On va avoir besoin de 2 variables pour effectuer nos calculs :
private double _CurrentScale = 1;
private double _StartScale = 1;
Et enfin on doit réagir à l’événement PinchUpdated :
private void CameraViewPinchGesture_PinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
{
if (e.Status == GestureStatus.Started)
{
_StartScale = CameraView.ZoomFactor;
}
else if (e.Status == GestureStatus.Running)
{
_CurrentScale += (e.Scale - 1) * _StartScale;
_CurrentScale = Math.Max(1, _CurrentScale);
if (_CurrentScale >= ZoomSlider.Minimum && _CurrentScale <= ZoomSlider.Maximum) ZoomSlider.Value = _CurrentScale;
}
}
Le calcul de _CurrentScale permet de déterminer, suivant l’étendue du pincement, quel facteur de zoom appliquer. Dans cet exemple il est appliqué (s’il est compris dans les bornes min et max) au Slider qui gère le zoom.
Conclusion
Et voilà, on a terminé ! Comme vous pouvez le constater c’est extrêmement simple comme mécanisme.
Vous pouvez récupérer tout le code de cet article sur Github et jouer avec d’autres « Gesture Recognizer ».
A bientôt.
Steph.