• 一个Pan&Zoom的Behavior


    Pan&Zoom是个很常用的操作,但是不想每次都去重新写各种GerstureListener事件,所以就参考这篇文章,改写了个简单的Behavior。

    public class ZoomAndPanBehavior2 : Behavior<Image>
    {
    private Image _currentImage { get { return AssociatedObject as Image; } }
     
    private PhoneApplicationPage _currentPage
    {
    get
    {
    var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
    var currentPage = rootFrame.Content as PhoneApplicationPage;
    return currentPage;
    }
    }
     
    private GestureListener _gl { get { return GestureService.GetGestureListener(_currentImage); } }
     
    private double _totalImageScale = 1d;
    private Point _imagePosition = new Point(0, 0);
     
    private Point _oldFinger1;
    private Point _oldFinger2;
    private double _oldScaleFactor; //旧的缩放因子
     
    private CompositeTransform _compositeTransfrom;
    private MatrixTransform _previousTransform;
    private TransformGroup _transfromGruop;
    private TransformGroup _currentGroup;
     
    bool isDragging;
    bool isPinching;
    Point ptPinchPositionStart;
     
    protected override void OnAttached()
    {
    base.OnAttached();
    _compositeTransfrom = new CompositeTransform();
    _previousTransform = new MatrixTransform { Matrix = Matrix.Identity };
    _transfromGruop = new TransformGroup();
    _currentGroup = new TransformGroup();
    _currentGroup.Children.Add(_compositeTransfrom);
    _transfromGruop.Children.Add(_currentGroup);
    _transfromGruop.Children.Add(_previousTransform);
    _currentImage.RenderTransform = _transfromGruop;
    _currentImage.RenderTransformOrigin = new Point(0, 0);
    _gl.DragStarted += _gl_DragStarted;
    _gl.DragDelta += _gl_DragDelta;
    _gl.PinchStarted += _gl_PinchStarted;
    _gl.PinchDelta += _gl_PinchDelta;
    _gl.PinchCompleted += _gl_PinchCompleted;
    _gl.Hold += _gl_Hold;
    _gl.DoubleTap += _gl_DoubleTap;
    }
     
    protected override void OnDetaching()
    {
    base.OnDetaching();
    _gl.DragStarted -= _gl_DragStarted;
    _gl.DragDelta -= _gl_DragDelta;
    _gl.PinchStarted -= _gl_PinchStarted;
    _gl.PinchDelta -= _gl_PinchDelta;
    _gl.PinchCompleted -= _gl_PinchCompleted;
    _gl.Hold -= _gl_Hold;
    _gl.DoubleTap -= _gl_DoubleTap;
    _compositeTransfrom = null;
    }
     
    void _gl_DoubleTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
    {
    Point imageCenter = e.GetPosition(_currentImage);
    if (_compositeTransfrom.ScaleX != 2)
    _compositeTransfrom.ScaleY = _compositeTransfrom.ScaleX = 2;
    else
    _compositeTransfrom.ScaleX = _compositeTransfrom.ScaleY = 1;
    _compositeTransfrom.CenterX = imageCenter.X;
    _compositeTransfrom.CenterY = imageCenter.Y;
    }
     
    void _gl_Hold(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
    {
     
    }
     
    void _gl_PinchStarted(object sender, PinchStartedGestureEventArgs e)
    {
    _oldFinger1 = e.GetPosition(_currentImage, 0);
    _oldFinger2 = e.GetPosition(_currentImage, 1);
    _oldScaleFactor = 1;
    isPinching = true;
    }
    void _gl_PinchDelta(object sender, PinchGestureEventArgs e)
    {
    //DistanceRatio表示缩放之后手指之间的距离与缩放前手指之间距离的比例
    var scaleFactor = e.DistanceRatio / _oldScaleFactor;
     
    var currentFinger1 = e.GetPosition(_currentImage, 0);
    var currentFinger2 = e.GetPosition(_currentImage, 1);
     
    Point tranlationDelta;
    tranlationDelta = GetTranslationDelta(currentFinger1, currentFinger2, _oldFinger1, _oldFinger2, _imagePosition, scaleFactor);
     
    _oldFinger1 = currentFinger1;
    _oldFinger2 = currentFinger2;
    _oldScaleFactor = e.DistanceRatio;
    UpdateImage(scaleFactor, tranlationDelta);
    }
     
    void _gl_PinchCompleted(object sender, PinchGestureEventArgs e)
    {
    isPinching = false;
    }
     
    void _gl_DragStarted(object sender, DragStartedGestureEventArgs e)
    {
     
    }
     
    void _gl_DragDelta(object sender, DragDeltaGestureEventArgs e)
    {
    if (isPinching)
    return;
    if (_totalImageScale > 1 || _compositeTransfrom.ScaleX > 1)
    {
    _compositeTransfrom.TranslateX += e.HorizontalChange;
    _compositeTransfrom.TranslateY += e.VerticalChange;
    }
    }
     
    private void UpdateImage(double scaleFactor, Point delta)
    {
    _totalImageScale *= scaleFactor;
    _imagePosition = new Point(_imagePosition.X + delta.X, _imagePosition.Y + delta.Y);
     
    if (_totalImageScale > 1)
    {
    _compositeTransfrom.ScaleX = _totalImageScale;
    _compositeTransfrom.ScaleY = _totalImageScale;
    _compositeTransfrom.TranslateX = _imagePosition.X;
    _compositeTransfrom.TranslateY = _imagePosition.Y;
    }
    else
    {
    _compositeTransfrom.ScaleX = _compositeTransfrom.ScaleY = 1;
    _compositeTransfrom.TranslateX = _compositeTransfrom.TranslateY = 0;
    _imagePosition = new Point(0, 0);
    }
    }
     
    private Point GetTranslationDelta(Point currentFinger1, Point currentFinger2, Point oldFinger1,
    Point oldFinger2, Point currentPosition, double scaleFactor)
    {
    var newPos1 = new Point(
    currentFinger1.X + (currentPosition.X - oldFinger1.X) * scaleFactor,
    currentFinger1.Y + (currentPosition.Y - oldFinger1.Y) * scaleFactor);
     
    var newPos2 = new Point(
    currentFinger2.X + (currentPosition.X - oldFinger2.X) * scaleFactor,
    currentFinger2.Y + (currentPosition.Y - oldFinger2.Y) * scaleFactor);
     
    var newPos = new Point(
    (newPos1.X + newPos2.X) / 2,
    (newPos1.Y + newPos2.Y) / 2);
     
    return new Point(
    newPos.X - currentPosition.X,
    newPos.Y - currentPosition.Y);
    }
    }

  • 相关阅读:
    linux下启动和关闭网卡命令及DHCP上网
    python 编码问题
    paddlepaddle
    Convolutional Neural Network Architectures for Matching Natural Language Sentences
    deep learning RNN
    Learning Structured Representation for Text Classification via Reinforcement Learning 学习笔记
    Python IO密集型任务、计算密集型任务,以及多线程、多进程
    EM 算法最好的解释
    tensorflow 调参过程
    tensorflow 学习纪录(持续更新)
  • 原文地址:https://www.cnblogs.com/walleyekneel/p/3133712.html
Copyright © 2020-2023  润新知