Créer des points d’ancrage avec des modificateurs d’inertie
Dans cet article, nous allons approfondir la façon d’utiliser la fonctionnalité InertieModifier d’InteractionTracker pour créer des expériences de mouvement qui s’alignent sur un point spécifié.
Prérequis
Ici, nous partons du principe que vous connaissez les concepts abordés dans ces articles :
- Animations pilotées par une entrée
- Expériences de manipulation personnalisées avec InteractionTracker
- Animations basées sur une relation
Qu’est-ce que les points d’ancrage et pourquoi sont-ils utiles ?
Lors de la création d’expériences de manipulation personnalisées, il est parfois utile de créer des points de position spécialisés dans le canevas défilement/zoomable auquel InteractionTracker viendra toujours se reposer. Ils sont souvent appelés points d’ancrage.
Notez dans l’exemple suivant comment le défilement peut laisser l’interface utilisateur dans une position maladroite entre les différentes images :
Si vous ajoutez des points d’ancrage, lorsque vous arrêtez de faire défiler les images, ils « s’alignent » à une position spécifiée. Avec les points d’ancrage, il rend l’expérience de défilement des images beaucoup plus propre et plus réactive.
InteractionTracker et InertieModifiers
Lors de la création d’expériences de manipulation personnalisées avec InteractionTracker, vous pouvez créer des expériences de mouvement de point d’ancrage en utilisant InertieModifiers. InertieModifiers est essentiellement un moyen de définir où ou comment InteractionTracker atteint sa destination lors de l’entrée de l’état Inertie. Vous pouvez appliquer des inertieModifiers pour affecter la position X ou Y ou les propriétés d’échelle d’InteractionTracker.
Il existe 3 types d’InertieModifiers :
- InteractionTrackerInertiaRestingValue : moyen de modifier la position de repos finale après une interaction ou une vitesse de programmation. Un mouvement prédéfini prend InteractionTracker à cette position.
- InteractionTrackerInertiaMotion : un moyen de définir un mouvement spécifique d’InteractionTracker s’effectue après une interaction ou une vélocité programmatique. La position finale sera dérivée de cette motion.
- InteractionTrackerInertiaNaturalMotion : un moyen de définir la position de repos finale après une interaction ou une vélocité programmatique, mais avec une animation physique (NaturalMotionAnimation).
Lors de la saisie de l’inertie, InteractionTracker évalue chacune des inertiemodifiers qui lui sont affectés et détermine si l’un d’eux s’applique. Cela signifie que vous pouvez créer et affecter plusieurs InertieModifiers à un InteractionTracker, mais, lors de la définition de chacun, vous devez effectuer les opérations suivantes :
- Définissez la condition : expression qui définit l’instruction conditionnelle lorsque cet inertieModifier spécifique doit avoir lieu. Cela nécessite souvent d’examiner NaturalRestingPosition d’InteractionTracker (destination donnée par défaut Inertie).
- Définissez restingValue/Motion/NaturalMotion : définissez l’expression de valeur resting réelle, l’expression de mouvement ou NaturalMotionAnimation qui se produit lorsque la condition est remplie.
Remarque
L’aspect condition des InertieModifiers n’est évalué qu’une seule fois lorsque InteractionTracker entre Inertie. Toutefois, uniquement pour InertieMotion, l’expression de mouvement est évaluée chaque image pour le modificateur dont la condition est vraie.
Exemple
Examinons maintenant comment utiliser InertieModifiers pour créer des expériences de point d’ancrage pour recréer le canevas de défilement des images. Dans cet exemple, chaque manipulation est destinée à se déplacer potentiellement dans une seule image : il s’agit souvent de points d’ancrage obligatoires uniques.
Commençons par configurer InteractionTracker, VisualInteractionSource et l’expression qui tireront parti de la position d’InteractionTracker.
private void SetupInput()
{
_tracker = InteractionTracker.Create(_compositor);
_tracker.MinPosition = new Vector3(0f);
_tracker.MaxPosition = new Vector3(3000f);
_source = VisualInteractionSource.Create(_root);
_source.ManipulationRedirectionMode =
VisualInteractionSourceRedirectionMode.CapableTouchpadOnly;
_source.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia;
_tracker.InteractionSources.Add(_source);
var scrollExp = _compositor.CreateExpressionAnimation("-tracker.Position.Y");
scrollExp.SetReferenceParameter("tracker", _tracker);
ElementCompositionPreview.GetElementVisual(scrollPanel).StartAnimation("Offset.Y", scrollExp);
}
Ensuite, étant donné qu’un comportement de point d’alignement obligatoire unique déplace le contenu vers le haut ou vers le bas, vous aurez besoin de deux modificateurs d’inertie différents : un qui déplace le contenu pouvant faire défiler le contenu vers le haut et un qui le déplace vers le bas.
// Snap-Point to move the content up
var snapUpModifier = InteractionTrackerInertiaRestingValue.Create(_compositor);
// Snap-Point to move the content down
var snapDownModifier = InteractionTrackerInertiaRestingValue.Create(_compositor);
Si l’alignement vers le haut ou le bas est déterminé en fonction de l’emplacement où InteractionTracker atterrirait naturellement par rapport à la distance d’ancrage , la distance entre les emplacements d’alignement. Si vous dépassez le point de mi-chemin, puis alignez-le, sinon enfichez-vous. (Dans cet exemple, vous stockez la distance d’alignement dans un PropertySet)
// Is NaturalRestingPosition less than the halfway point between Snap Points?
snapUpModifier.Condition = _compositor.CreateExpressionAnimation(
"this.Target.NaturalRestingPosition.y < (this.StartingValue - " +
"mod(this.StartingValue, prop.snapDistance) + prop.snapDistance / 2)");
snapUpModifier.Condition.SetReferenceParameter("prop", _propSet);
// Is NaturalRestingPosition greater than the halfway point between Snap Points?
snapDownModifier.Condition = _compositor.CreateExpressionAnimation(
"this.Target.NaturalRestingPosition.y >= (this.StartingValue - " +
"mod(this.StartingValue, prop.snapDistance) + prop.snapDistance / 2)");
snapDownModifier.Condition.SetReferenceParameter("prop", _propSet);
Ce diagramme donne une description visuelle à la logique qui se produit :
Maintenant, vous devez simplement définir les valeurs de repos pour chaque inertieModifier : déplacez la position d’InteractionTracker vers la position d’alignement précédente ou la suivante.
snapUpModifier.RestingValue = _compositor.CreateExpressionAnimation(
"this.StartingValue - mod(this.StartingValue, prop.snapDistance)");
snapUpModifier.RestingValue.SetReferenceParameter("prop", _propSet);
snapDownModifier.RestingValue = _compositor.CreateExpressionAnimation(
"this.StartingValue + prop.snapDistance - mod(this.StartingValue, " +
"prop.snapDistance)");
snapDownModifier.RestingValue.SetReferenceParameter("prop", _propSet);
Enfin, ajoutez les InertieModifiers à InteractionTracker. À présent, lorsque InteractionTracker entre dans l’état d’inertie, il vérifie les conditions de vos inertiemodifiers pour voir si sa position doit être modifiée.
var modifiers = new InteractionTrackerInertiaRestingValue[] {
snapUpModifier, snapDownModifier };
_tracker.ConfigurePositionYInertiaModifiers(modifiers);