Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pinch Zoom - Getting touch coordinates

Tags:

windows

winjs

I am developing a Windows 8 app using WinJS. I am trying to get the touch coordinates for pinch and zoom. I have implemented the gesture manipulation handlers via Windows.UI.Input.GestureRecognizer. I am triggering my pinch and zoom logic when for the "manipulationupdated" event, event.delta.scale is not 1. When manipulation happens inside the "manipulationupdated" event object I find coordinates of only 1 position. How do I calculate both the finger touch coordinates from this information?

Also how do I know which touch coordinate the position belong to? I find the position repeated multiple times inside the event object - at event.position and event.detail[0].position

What I am trying to achieve is performing pinch and zoom in a chart(much like a map). Kindly help me out with these questions.

like image 665
Jithin Avatar asked Nov 13 '22 20:11

Jithin


1 Answers

public class PZBehavior : Behavior {

    bool _isDragging;
    bool _isPinching;
    Point _ptPinchPositionStart;

    private Image _imgZoom;
    private ScaleTransform _scaleTransform;
    private RotateTransform _rotateTransform;
    private TranslateTransform _translateTransform;
    private MatrixTransform _previousTransform;

    private TransformGroup _parentGroup;
    private TransformGroup _currentTransform;



    protected override void OnAttached()
    {
        _imgZoom = AssociatedObject;
        _imgZoom.RenderTransform = BuildTrasnformGroup();
        var listener = GestureService.GetGestureListener(AssociatedObject);
        listener.DragStarted += DragStarted;
        listener.DragDelta += DragDelta;
        listener.DragCompleted += DragCompleted;
        listener.PinchStarted += PinchStarted;
        listener.PinchDelta += PinchDelta;
        listener.PinchCompleted += PinchCompleted;
    }


    private TransformGroup BuildTrasnformGroup()
    {
        _parentGroup = new TransformGroup();
        _currentTransform = new TransformGroup();

        _previousTransform = new MatrixTransform();

        _scaleTransform = new ScaleTransform();
        _rotateTransform = new RotateTransform();
        _translateTransform = new TranslateTransform();

        _currentTransform.Children.Add(_scaleTransform);
        _currentTransform.Children.Add(_rotateTransform);
        _currentTransform.Children.Add(_translateTransform);

        _parentGroup.Children.Add(_previousTransform);
        _parentGroup.Children.Add(_currentTransform);

        return _parentGroup;

    }


    void PinchCompleted(object sender, PinchGestureEventArgs e)
    {
        if (_isPinching)
        {
            TransferTransforms();
            _isPinching = false;
        }
    }

    void PinchDelta(object sender, PinchGestureEventArgs e)
    {
        if (_isPinching)
        {
            // Set scaling
            _scaleTransform.ScaleX = e.DistanceRatio;
            _scaleTransform.ScaleY = e.DistanceRatio;

            // Optionally set rotation

            _rotateTransform.Angle = e.TotalAngleDelta;

            // Set translation
            Point ptPinchPosition = new Point(0,0);
            _translateTransform.X = ptPinchPosition.X - _ptPinchPositionStart.X;
            _translateTransform.Y = ptPinchPosition.Y - _ptPinchPositionStart.Y;
        }
    }

    void PinchStarted(object sender, PinchStartedGestureEventArgs e)
    {
        _isPinching = e.OriginalSource == _imgZoom;

        if (_isPinching)
        {
            // Set transform centers
            Point ptPinchCenter = e.GetPosition(_imgZoom);
            ptPinchCenter = _previousTransform.Transform(ptPinchCenter);

            _scaleTransform.CenterX = ptPinchCenter.X;
            _scaleTransform.CenterY = ptPinchCenter.Y;

            _rotateTransform.CenterX = ptPinchCenter.X;
            _rotateTransform.CenterY = ptPinchCenter.Y;

            _ptPinchPositionStart = new Point(0,0);
        }
    }

    void DragCompleted(object sender, DragCompletedGestureEventArgs e)
    {
        if (_isDragging)
        {
            TransferTransforms();
            _isDragging = false;
        }
    }

    void DragDelta(object sender, DragDeltaGestureEventArgs e)
    {
        if (_isDragging)
        {
            _translateTransform.X += e.HorizontalChange;
            _translateTransform.Y += e.VerticalChange;
        }
    }

    void DragStarted(object sender, DragStartedGestureEventArgs e)
    {
        _isDragging = e.OriginalSource == _imgZoom;

    }

    void TransferTransforms()
    {
        _previousTransform.Matrix = Multiply(_previousTransform.Matrix, _currentTransform.Value);

        // Set current transforms to default values
        _scaleTransform.ScaleX = _scaleTransform.ScaleY = 1;
        _scaleTransform.CenterX = _scaleTransform.CenterY = 0;

        _rotateTransform.Angle = 0;
        _rotateTransform.CenterX = _rotateTransform.CenterY = 0;

        _translateTransform.X = _translateTransform.Y = 0;
    }

    Matrix Multiply(Matrix a, Matrix b)
    {
        return new Matrix(a.M11 * b.M11 + a.M12 * b.M21,
                          a.M11 * b.M12 + a.M12 * b.M22,
                          a.M21 * b.M11 + a.M22 * b.M21,
                          a.M21 * b.M12 + a.M22 * b.M22,
                          a.OffsetX * b.M11 + a.OffsetY * b.M21 + b.OffsetX,
                          a.OffsetX * b.M12 + a.OffsetY * b.M22 + b.OffsetY);
    }
}
like image 146
Stephan Ronald Avatar answered Dec 05 '22 00:12

Stephan Ronald