Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
295 views
in Technique[技术] by (71.8m points)

c# - Move the zoomed image by gyroscope in xamarin

I want to move the zoomed image with gyroscope. As you can see in below code I can do this thing by hand and I got a good result. I have to write something inside "Gyroscope_ReadingChanged" to convert gyroscope data to the Content.TranslationX and Content.TranslationY. Any help would be appreciated.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         xmlns:video="clr-namespace:UbSports.Controls"
         xmlns:local="clr-namespace:UbSports.Controls"
         x:Class="UbSports.Pages.TestPage"> 
 
    <local:PinchToZoomContainer VerticalOptions="FillAndExpand">
        <local:PinchToZoomContainer.Content>
            <Image x:Name="image" Source="waterfront.jpg" />
        </local:PinchToZoomContainer.Content>
    </local:PinchToZoomContainer>

</ContentPage>

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestPage: ContentPage
{
    public TestPage()
    {
        InitializeComponent();
    }
}

public class PinchToZoomContainer : ContentView
{
    public PinchToZoomContainer()
    {
        Gyroscope.ReadingChanged += Gyroscope_ReadingChanged;
        try
        {
            Gyroscope.Start(SensorSpeed.UI);
        }
        catch (FeatureNotSupportedException fnsEx)
        {
             
        }
        catch (Exception ex)
        {
             
        }

        var panGesture = new PanGestureRecognizer();
        panGesture.PanUpdated += OnPanUpdated;
        GestureRecognizers.Add(panGesture);

        var pinchGesture = new PinchGestureRecognizer();
        pinchGesture.PinchUpdated += OnPinchUpdated;
        GestureRecognizers.Add(pinchGesture);
    }
   
    void Gyroscope_ReadingChanged(object sender, GyroscopeChangedEventArgs e)
    {
         var data = e.Reading;
         if (data.AngularVelocity.X == 0 && data.AngularVelocity.Y == 0) return;
         
        // do something
    }

    void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    { 
        switch (e.StatusType)
        {
            case GestureStatus.Started:
                startX = e.TotalX;
                startY = e.TotalY;
                Content.AnchorX = 0;
                Content.AnchorY = 0;

                break;

            case GestureStatus.Running:
                var maxTranslationX = Content.Scale * Content.Width - Content.Width;
                Content.TranslationX = Math.Min(0, Math.Max(-maxTranslationX, xOffset + e.TotalX - startX));

                var maxTranslationY = Content.Scale * Content.Height - Content.Height;
                Content.TranslationY = Math.Min(0, Math.Max(-maxTranslationY, yOffset + e.TotalY - startY));

                break;

            case GestureStatus.Completed:
                xOffset = Content.TranslationX;
                yOffset = Content.TranslationY;

                break;
        }
    }
    
    void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
    {
        if (e.Status == GestureStatus.Started)
        { 
            startScale = Content.Scale;
            Content.AnchorX = 0;
            Content.AnchorY = 0;
        }
        if (e.Status == GestureStatus.Running)
        { 
            currentScale += (e.Scale - 1) * startScale;
            currentScale = Math.Max(1, currentScale);
             
            double renderedX = Content.X + xOffset;
            double deltaX = renderedX / Width;
            double deltaWidth = Width / (Content.Width * startScale);
            double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;
             
            double renderedY = Content.Y + yOffset;
            double deltaY = renderedY / Height;
            double deltaHeight = Height / (Content.Height * startScale);
            double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;
             
            double targetX = xOffset - (originX * Content.Width) * (currentScale - startScale);
            double targetY = yOffset - (originY * Content.Height) * (currentScale - startScale);
             
            Content.TranslationX = targetX.Clamp(-Content.Width * (currentScale - 1), 0);
            Content.TranslationY = targetY.Clamp(-Content.Height * (currentScale - 1), 0);
             
            Content.Scale = currentScale;
        }
        if (e.Status == GestureStatus.Completed)
        { 
            xOffset = Content.TranslationX;
            yOffset = Content.TranslationY;
        }
    }
    
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...