2017-08-03 2 views
1

J'ai une question sur les animations dans UWP. Je veux avoir un menu en bas de mon application qui, lorsqu'il est tapé sur le dessus, glisse vers le haut (montre) ou vers le bas (se cache presque entièrement). J'apprenais WPF avant et là je sais que je peux utiliser ThicknessAnimation pour déplacer la marge de mon contrôle et le faire glisser. Malheureusement, dans UWP je ne peux pas utiliser ThicknessAnimations, alors j'ai essayé de trouver un autre moyen. Je veux que cela fonctionne pour un FrameworkElement arbitraire (afin de pouvoir le réutiliser). Finalement, je suis venu avec cette solution:Éléments coulissants dans C# UWP

/// <summary> 
    /// Adds a vertical slide animation 
    /// </summary> 
    /// <param name="storyboard">The storyboard to add the animation to</param> 
    /// <param name="seconds">The time the animation will take</param> 
    /// <param name="offset">The distance the element will cover (nagative is up, positive is down)</param> 
    public static void AddVerticalSlide(this Storyboard storyboard, FrameworkElement element, float seconds, double offset) 
    { 

     var slideAnimation = new ObjectAnimationUsingKeyFrames();  

     for (int i = 0; i <= 100; ++i) 
     { 
      double scalar = (double)i/100; 
      slideAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame 
      {     
       Value = new Thickness(0, scalar*offset, 0, -scalar*offset), 
       KeyTime = TimeSpan.FromSeconds(scalar*seconds), 
      }); 
     } 

     //slideAnimation.Duration = TimeSpan.FromSeconds(seconds); 

     // Set the target and target property 
     Storyboard.SetTarget(slideAnimation, element); 
     Storyboard.SetTargetProperty(slideAnimation, "(FrameworkElement.Margin)"); 

     // Add the animation to the storyboard 
     storyboard.Children.Add(slideAnimation); 
    } 

Il fonctionne, l'air bien, mais voici la raison pour laquelle je pose cette question: Je ne sais pas s'il est bon. Mon idée est qu'il existe une meilleure façon de faire glisser des objets que de définir manuellement 100 points sur le chemin et de déplacer l'objet à chaque point en utilisant cette animation.

Répondre

1

Cela fonctionne mais n'est pas le moyen idéal pour offset un élément. Pourquoi? Parce que vous créez deux beaucoup DiscreteObjectKeyFrame lorsque vous avez juste besoin de unDoubleAnimation.

Vous ne devriez presque jamais animer le Margin d'un élément. Pour modifier sa position, une meilleure approche consiste à animer les valeurs de traduction (c'est-à-dire TranslateX/TranslateY) de sa transformation (RenderTransform) à la place. L'animation de n'importe quoi dans la transformation est efficace. Ils sont hors du fil de l'interface utilisateur. Traditionnellement, ils étaient en cours d'exécution dans un thread spécial appelé Compositor fil (je pense), mais jamais depuis la Les créateurs de mise à jour, ils sont devenus encore plus performants selon la Windows UI team -

Lorsque vous utilisez Storyboard et Transitions animations en XAML, vous êtes en utilisant la composition sous le capot. Les animations tournent à 60 images par secondes!

Voici un exemple d'utilisation de cette technique

public static void Slide(this UIElement target, Orientation orientation, double? from, double to, int duration = 400, int startTime = 0, EasingFunctionBase easing = null) 
{ 
    if (easing == null) 
    { 
     easing = new ExponentialEase(); 
    } 

    var transform = target.RenderTransform as CompositeTransform; 
    if (transform == null) 
    { 
     transform = new CompositeTransform(); 
     target.RenderTransform = transform; 
    } 
    target.RenderTransformOrigin = new Point(0.5, 0.5); 

    var db = new DoubleAnimation 
    { 
     To = to, 
     From = from, 
     EasingFunction = easing, 
     Duration = TimeSpan.FromMilliseconds(duration) 
    }; 
    Storyboard.SetTarget(db, target); 
    var axis = orientation == Orientation.Horizontal ? "X" : "Y"; 
    Storyboard.SetTargetProperty(db, $"(UIElement.RenderTransform).(CompositeTransform.Translate{axis})"); 

    var sb = new Storyboard 
    { 
     BeginTime = TimeSpan.FromMilliseconds(startTime) 
    }; 

    sb.Children.Add(db); 
    sb.Begin(); 
} 

Notez que cette approche que performante obtient, il y a le soutien d'animation encore plus puissant UWP, grâce à la nouvelle API de composition. Mais l'animation offset dans Composition peut être un peu tricky.

Cependant, la UWP communautaire Tookit a fait un excellent travail d'emballage des animations utiles comme Blur, Offset, etc. Ne hésitez pas à vérifier them out.