Dela via


Skapa snappunkter med tröghetsmodifierare

I denna artikel tar vi en djupare titt på hur du använder InteractionTrackerns InertiaModifier-funktion för att skapa rörelseupplevelser som snäppar till en angiven punkt.

Förutsättningar

Här förutsätter vi att du är bekant med de begrepp som beskrivs i dessa artiklar:

Vad är fästpunkter och varför är de användbara?

När du skapar anpassade manipulationsupplevelser är det ibland bra att skapa specialiserade positioneringspunkter inom den rullningsbara/zoombara arbetsytan som InteractionTracker alltid kommer att stanna vid. Dessa kallas ofta snappunkter.

Observera i följande exempel hur rullningen kan lämna användargränssnittet i en besvärlig position mellan de olika bilderna:

Rullning utan fästpunkter

Om du lägger till fästpunkter, när du slutar rulla mellan bilderna, "fäster" de till en angiven position. Med snappunkter görs upplevelsen av att bläddra igenom bilder mycket renare och mer responsiv.

Rullning med en enda fästpunkt

InteractionTracker och InertiaModifiers

När du skapar anpassade manipulationsupplevelser med InteractionTracker kan du skapa snabbpunktsrörelser genom att använda InertiaModifiers. InertiaModifiers är i princip ett sätt för dig att definiera var eller hur InteractionTracker når sitt mål när du anger tröghetstillståndet. Du kan använda InertiaModifiers för att påverka X- eller Y-positionen eller skalningsegenskaperna för InteractionTracker.

Det finns tre typer av InertiaModifiers:

  • InteractionTrackerInertiaRestingValue – ett sätt att ändra den slutliga vilopositionen efter en interaktion eller programmeringshastighet. En fördefinierad rörelse tar InteractionTracker till den positionen.
  • InteractionTrackerInertiaMotion – ett sätt att definiera ett specifikt rörelsemönster som InteractionTracker kommer att utföra efter en interaktion eller programmerad hastighet. Den slutliga positionen kommer att härledas från denna motion.
  • InteractionTrackerInertiaNaturalMotion – ett sätt att definiera den slutliga vilopositionen efter en interaktion eller programmeringshastighet men med en fysikbaserad animering (NaturalMotionAnimation).

När du går in i tröghetsläge utvärderar InteractionTracker varje InertiaModifier som har tilldelats och avgör om någon av dem är tillämplig. Det innebär att du kan skapa och tilldela flera InertiaModifiers till en InteractionTracker, men när du definierar var och en måste du göra följande:

  1. Definiera villkoret – ett uttryck som definierar villkorssatsen när den här specifika InertiaModifier ska äga rum. Detta kräver ofta att du granskar egenskapen NaturalRestingPosition i InteractionTracker (destination vid standardtröghet).
  2. Definiera RestingValue/Motion/NaturalMotion – definiera det faktiska vilovärdeuttrycket, rörelseuttrycket eller NaturalMotionAnimation som inträffar när villkoret är uppfyllt.

Anmärkning

Villkorsaspekten för InertiaModifiers utvärderas bara en gång när InteractionTracker går in i Tröghet. Men endast för InertiaMotion utvärderas Rörelseuttrycket varje bildruta för den modifieraren vars villkor är sanna.

Exempel

Nu ska vi titta på hur du kan använda InertiaModifiers för att skapa några synupplevelser med snappunkter för att återskapa den rullande duken med bilder. I det här exemplet är varje manipulering avsedd att potentiellt gå igenom en enda bild – detta kallas ofta för enkla obligatoriska snappunkter.

Vi börjar med att konfigurera InteractionTracker, VisualInteractionSource och uttrycket som använder positionen för 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);
}

Eftersom ett enda obligatoriskt snappunktsbeteende antingen flyttar innehållet uppåt eller nedåt behöver du två olika tröghetsmodifierare: en som flyttar upp det rullningsbara innehållet och ett som flyttar ned det.

// Snap-Point to move the content up
var snapUpModifier = InteractionTrackerInertiaRestingValue.Create(_compositor);
// Snap-Point to move the content down
var snapDownModifier = InteractionTrackerInertiaRestingValue.Create(_compositor);

Huruvida man ska snappa uppåt eller nedåt bestäms baserat på var InteractionTracker naturligt skulle hamna i förhållande till snapavståndet – alltså avståndet mellan fästplatserna. Om du har passerat halvvägs, tryck ner, annars tryck upp. (I det här exemplet lagrar du fästavståndet i en egenskapsuppsättning)

// 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);

Det här diagrammet ger en visuell beskrivning av logiken som händer:

inertiamodifier diagram

Nu behöver du bara definiera vilande värden för varje InertiaModifier: antingen flytta positionen för InteractionTracker till den tidigare snappositionen eller nästa.

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

Lägg slutligen till InertiaModifiers i InteractionTracker. Nu när InteractionTracker kommer in i inertiaState kontrollerar den villkoren för dina InertiaModifiers för att se om dess position ska ändras.

var modifiers = new InteractionTrackerInertiaRestingValue[] { 
snapUpModifier, snapDownModifier };
_tracker.ConfigurePositionYInertiaModifiers(modifiers);