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. Which I can do with
Viewportcontroller.SetViewportOrigin()
But this makes the viewportcontroller jump to the origin I set. Which does not look very nice. I therefore would like to create a storyboard that changes the origin gradually as the zooming occurs.
I therefore would like to ask how I should do this with a property of the ViewportControl. I have tried with some different animation types, translation and xy. But either I am choosing the property wrong or choosing the wrong animation type. Because nothing is working :(
My Problem is therefore twofold.
What type of animation do I choose. And how do I change it?
Should it be a DoubleAnimation Where I set to and from? But I Cannot seem to set a point here? Any help IS MUCH APPRECIATED!
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();
}
}
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