Difficult and unatural Pinch behavior in Maui

Austin Oberholtzer 0 Reputation points
2024-02-28T18:11:40.5866667+00:00

We have implemented the Pinch container as per the example for Maui. The pinch itself works pretty ok, but if you pinch and pan the actual behavior is quite clunky and horrible to be honest. It does not feel natural like native pinch/pan logic on the photos app or anywhere else really in Maui. My suspicion is the handling of the scale/zoom and then transitioning does not translate well.

I need to retain only pinch as singular touch is used for drawing. Any help would be greatly appreciated

if (e.Status == GestureStatus.Started)
{
    startScale = Content.Scale;
    Content.AnchorX = 0;
    Content.AnchorY = 0;
}

if (e.Status == GestureStatus.Running)
{
    // Calculate the scale factor to be applied.
    currentScale += (e.Scale - 1) * startScale;
    currentScale = Math.Max(1, currentScale);

    // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
    // so get the X pixel coordinate.
    var renderedX = Content.X + xOffset;
    var deltaX = renderedX / Width;
    var deltaWidth = Width / (Content.Width * startScale);
    var originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;

    // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
    // so get the Y pixel coordinate.
    var renderedY = Content.Y + yOffset;
    var deltaY = renderedY / Height;
    var deltaHeight = Height / (Content.Height * startScale);
    var originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;

    // Calculate the transformed element pixel coordinates.
    var targetX = xOffset - ((originX * Content.Width) * (currentScale - startScale));
    var targetY = yOffset - ((originY * Content.Height) * (currentScale - startScale));

    // Apply translation based on the change in origin.
    Content.TranslationX = Math.Clamp(targetX, -Content.Width * (currentScale - 1), 0);
    Content.TranslationY = Math.Clamp(targetY, -Content.Height * (currentScale - 1), 0);

    // Apply scale factor
    Content.Scale = currentScale;
}

if (e.Status == GestureStatus.Completed)
{
    // Store the translation delta's of the wrapped user interface element.
    xOffset = Content.TranslationX;
    yOffset = Content.TranslationY;
}

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
2,855 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.

    2 deleted comments

    Comments have been turned off. Learn more

  2. Pinaki Ghatak 2,320 Reputation points Microsoft Employee
    2024-03-02T18:30:43.1366667+00:00

    Hello @Austin Oberholtzer

    The code you’ve shared is a common way to implement pinch to zoom functionality. However, if you’re finding that the transition between pinching and panning is not smooth, it could be due to how the gestures are being handled.

    One thing you could try is to separate the pinch and pan gestures. This means having one GestureRecognizer for pinch and another for pan. This way, you can control the conditions under which each gesture is allowed to start, ensuring that they don’t interfere with each other.

    Here’s a short example to illustrate how you might implement this:

    var pinchGesture = new PinchGestureRecognizer();
    pinchGesture.PinchUpdated += OnPinchUpdated;
    Content.GestureRecognizers.Add(pinchGesture);
    
    var panGesture = new PanGestureRecognizer();
    panGesture.PanUpdated += OnPanUpdated;
    Content.GestureRecognizers.Add(panGesture);
    
    

    In the OnPinchUpdated and OnPanUpdated methods, you would implement the logic for each gesture. You could use a flag to check if a pinch is in progress and ignore pan updates during this time, and vice versa.

    Remember, the key is to ensure that the gestures do not conflict with each other, which can result in a clunky user experience.

    I hope the above examples provided help in your journey.


    If this information provided here helps solve your issue, please tag this as answered, so it helps further community readers, who may have similar questions.

    0 comments No comments