Viewport Origin animation

前端 未结 2 993
感动是毒
感动是毒 2021-01-21 07:01

I am developing a Windows phone app, where I have a viewportcontroller, that enables me to zoom in and out on content. I want to center the zoom at the point where I zoom. Whic

相关标签:
2条回答
  • 2021-01-21 07:53

    I tried a few different approaches and this one came out to be the smoothest. It's not pretty, but it works.

    public partial class MainPage : PhoneApplicationPage
    {
        private const int MoveCount = 25;
    
        private double _tickX;
        private double _tickY;
    
        private int _adjustCount = MoveCount+1;
    
        public MainPage()
        {
            InitializeComponent();
            Viewport.ViewportChanged += ViewportOnViewportChanged;
        }
    
        private void ViewportOnViewportChanged(object sender, ViewportChangedEventArgs viewportChangedEventArgs)
        {
            AdjstViewport();
        }
    
        private void AdjstViewport()
        {
            if (_adjustCount >= MoveCount) return;
            _adjustCount++;
            Viewport.SetViewportOrigin(new Point(Viewport.Viewport.X + _tickX, Viewport.Viewport.Y + _tickY));                        
        }
    
        private async void OnButtonClick(object sender, System.Windows.RoutedEventArgs e)
        {
            _adjustCount = 0;
    
            var content = (FrameworkElement)Viewport.Content;
            double zoomOriginX = (content.ActualWidth / 2) - (Viewport.Viewport.Width / 2);
            double zoomOriginY = (content.ActualHeight / 2) - (Viewport.Viewport.Height / 2);
    
            double distanceX = zoomOriginX - Viewport.Viewport.X;
            double distanceY = zoomOriginY - Viewport.Viewport.Y;
    
            _tickX = distanceX / MoveCount;
            _tickY = distanceY / MoveCount;
    
            AdjstViewport();
        }
    }
    
    0 讨论(0)
  • 2021-01-21 07:57

    I have no experience with the ViewportControl, and I am assuming ViewportControl.SetViewportOrigin() is the only way to set the origin (i.e. : there are no properties to do it).

    If that's the case, you could wrap the ViewportControl in a custom control.

    Add two dependency properties that control (ViewportX and ViewportY, or one dependency property of type Point), and in the storyboard, animate those two properties (with a simple DoubleAnimation).

    In the value changed callbacks of those properties, you can then call SetViewportOrigin() with the changed values.

    so something like:

    public class WrappedViewport : Control
    {
        private ViewportControl _viewportControl;
        protected override OnApplyTemplate()
        {
            // make sure there is an appropriate default style in generic.xaml
            _viewportControl = (ViewportControl)GetTemplateChild("Viewport"); 
        }
    
        #region ViewportX
        private static void ViewportXChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            WrappedViewport owner = (WrappedViewport)d;
            owner._viewportControl.SetViewportOrigin(ViewportX, ViewportY);
        }
    
        private static readonly DependencyProperty ViewportXProperty = DependencyProperty.Register("ViewportX",
                                                                                              typeof(double),
                                                                                              typeof(WrappedViewport),
                                                                                              new PropertyMetadata(0d, ViewportXChangedCallback));
    
        public double ViewportX
        {
            get { return (double)GetValue(ViewportXProperty ); }
            set { SetValue(ViewportXProperty , value); }
        }
        #endregion
    
        #region ViewportY
        private static void ViewportYChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            WrappedViewport owner = (WrappedViewport)d;
            owner._viewportControl.SetViewportOrigin(ViewportX, ViewportY);
        }
    
        private static readonly DependencyProperty ViewportYProperty = DependencyProperty.Register("ViewportY",
                                                                                              typeof(double),
                                                                                              typeof(WrappedViewport),
                                                                                              new PropertyMetadata(0d, ViewportYChangedCallback));
    
        public double ViewportY
        {
            get { return (double)GetValue(ViewportYProperty ); }
            set { SetValue(ViewportYProperty , value); }
        }
        #endregion
    }
    

    See also http://msdn.microsoft.com/en-us/library/ms752914(v=vs.110).aspx

    0 讨论(0)
提交回复
热议问题