Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo, se profundiza en cómo usar la característica InteractionTracker InertiaModifier para crear experiencias de movimiento que se ajusten a un punto especificado.
Prerrequisitos
Aquí se supone que está familiarizado con los conceptos descritos en estos artículos:
- animaciones controladas por entrada
- experiencias personalizadas de manipulación con InteractionTracker
- animaciones basadas en Relation
¿Qué son los puntos de acoplamiento y por qué son útiles?
Al crear experiencias de manipulación personalizadas, a veces resulta útil crear puntos de posición especializados dentro del lienzo desplazable o zoomable en el que InteractionTracker siempre descansará. A menudo se denominan puntos de acoplamiento .
Observe en el ejemplo siguiente cómo el desplazamiento puede dejar la interfaz de usuario en una posición torpe entre las distintas imágenes:
Cuando se agregan puntos de ajuste, al dejar de desplazarse entre las imágenes, estas se ajustan a una posición especificada. Con puntos de acoplamiento, hace que la experiencia de desplazarse por imágenes sea mucho más limpia y con mayor capacidad de respuesta.
InteractionTracker e InertiaModifiers
Al crear experiencias personalizadas de manipulación con InteractionTracker, puede generar experiencias de movimiento por puntos de acoplamiento mediante modificadores de inercia. Los modificadores de inercia son básicamente una forma de definir dónde o cómo InteractionTracker alcanza su destino al entrar en el estado de inercia. Puede aplicar InertiaModifiers para afectar las propiedades X o Y, o la escala de InteractionTracker.
Hay 3 tipos de InertiaModifiers:
- InteractionTrackerInertiaRestingValue: una manera de modificar la posición final de reposo después de una interacción o velocidad programática. Un movimiento predefinido tomará InteractionTracker a esa posición.
- InteractionTrackerInertiaMotion: una forma de definir un movimiento específico que el InteractionTracker realizará después de una interacción o una velocidad programada. La posición final se derivará de este movimiento.
- InteractionTrackerInertiaNaturalMotion: una manera de definir la posición de reposo final después de una interacción o velocidad programática, pero con una animación basada en física (NaturalMotionAnimation).
Al entrar en Inercia, InteractionTracker evalúa cada uno de los InertiaModifiers asignados a él y determina si alguno de ellos se aplica. Esto significa que puede crear y asignar varios InerciaModifiers a interactionTracker, pero, al definir cada uno, debe hacer lo siguiente:
- Definir la condición: una expresión que determina cuándo debe aplicarse este InertiaModifier específico. Esto a menudo requiere examinar la posición natural de reposo de InteractionTracker (destino dada la inercia predeterminada).
- Definir restingValue/Motion/NaturalMotion: defina la expresión de valor restante real, la expresión de movimiento o naturalMotionAnimation que tiene lugar cuando se cumple la condición.
Nota:
El aspecto de condición de los InertiaModifiers solo se evalúa una vez cuando InteractionTracker entra en Inercia. Sin embargo, solo para InertiaMotion, la expresión de movimiento se evalúa en cada cuadro para el modificador cuya condición es verdadera.
Ejemplo
Veamos ahora cómo puedes utilizar InertiaModifiers para crear algunas experiencias de puntos de encaje y así recrear el desplazamiento del lienzo de imágenes. En este ejemplo, cada manipulación está pensada para desplazarse potencialmente a través de una sola imagen: esto se conoce a menudo como puntos de acoplamiento obligatorios únicos.
Comencemos configurando InteractionTracker, VisualInteractionSource y la expresión que aprovecharán la posición de 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);
}
A continuación, dado que el comportamiento de un "Single Mandatory Snap Point" moverá el contenido ya sea hacia arriba o hacia abajo, necesitará dos modificadores de inercia diferentes: uno que suba el contenido desplazable y otro que lo baje.
// Snap-Point to move the content up
var snapUpModifier = InteractionTrackerInertiaRestingValue.Create(_compositor);
// Snap-Point to move the content down
var snapDownModifier = InteractionTrackerInertiaRestingValue.Create(_compositor);
Se decide si se debe ajustar hacia arriba o hacia abajo en función de dónde InteractionTracker se colocaría naturalmente en relación con la distancia de ajuste, que es la distancia entre las ubicaciones de ajuste. Si ha pasado el punto medio, entonces presione hacia abajo; de lo contrario, eleve hacia arriba. (En este ejemplo, almacenas la distancia de ajuste en 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);
Este diagrama proporciona una descripción visual a la lógica que está ocurriendo:
Ahora solo tiene que definir los valores de reposo para cada modificador de inercia: mover la posición de InteractionTracker a la posición de ajuste anterior o la siguiente.
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);
Por último, agregue los InertiaModifiers a InteractionTracker. Ahora, cuando InteractionTracker entra en inerciaState, comprobará las condiciones de los InerciaModifiers para ver si se debe modificar su posición.
var modifiers = new InteractionTrackerInertiaRestingValue[] {
snapUpModifier, snapDownModifier };
_tracker.ConfigurePositionYInertiaModifiers(modifiers);