视口原点动画

时间:2014-03-09 15:02:51

标签: c# animation windows-phone-8 storyboard

我正在开发一个Windows手机应用程序,我有一个viewportcontroller,可以放大和缩小内容。 我想将变焦对准我缩放的点。

我可以做些什么
Viewportcontroller.SetViewportOrigin()

但这会使viewportcontroller跳转到我设置的原点。哪个看起来不太好看。因此,我想创建一个故事板,在变焦发生时逐渐改变原点。

因此,我想问一下如何使用ViewportControl的属性执行此操作。我尝试过一些不同的动画类型,翻译和xy。但要么是我选择了错误的属性,要么选择了错误的动画类型。因为没有任何工作:(

因此我的问题是双重的。 我选择什么类型的动画。我该如何改变呢? 它应该是DoubleAnimation我在哪里设置和来自?但我似乎无法在这里说明一点?任何帮助都很受欢迎!

2 个答案:

答案 0 :(得分:3)

我没有ViewportControl的经验,我假设ViewportControl.SetViewportOrigin()是设置原点的唯一方法(即:没有属性可以做到)。

如果是这种情况,您可以将ViewportControl包装在自定义控件中。

添加两个控制的依赖项属性(ViewportX和ViewportY,或Point类型的一个依赖项属性),并在故事板中为这两个属性设置动画(使用简单的DoubleAnimation)。

在这些属性的值更改回调中,您可以使用更改的值调用SetViewportOrigin()。

如下所示:

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
}

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

答案 1 :(得分:1)

我尝试了几种不同的方法,这一方法最为顺畅。它不漂亮,但它有效。

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();
    }
}