Delen via


Snappunten maken met traagheidsmodificaties

In dit artikel gaan we dieper in op het gebruik van de InertiaModifier-functie van InteractionTracker om een bewegingservaring te creëren die vastklikt op een opgegeven punt in een WinUI-app.

In WinUI-apps InteractionTracker en de gerelateerde wijzigingstypen voor traagheid bevinden zich in de Microsoft.UI.Composition.Interactions naamruimte.

Vereiste voorwaarden

Hier gaan we ervan uit dat u bekend bent met de concepten die in deze artikelen worden besproken:

Wat zijn uitlijnpunten en waarom zijn ze nuttig?

Bij het bouwen van aangepaste manipulatie-ervaringen is het soms handig om gespecialiseerde positiepunten te maken binnen het schuifbare/zoombare canvas waar InteractionTracker altijd in rust komt. Dit worden vaak snappunten genoemd.

In het volgende voorbeeld ziet u hoe de gebruikersinterface met schuiven in een onhandige positie tussen de verschillende afbeeldingen kan blijven:

Scrollen zonder snap-punten

Als u uitlijnpunten toevoegt en u stopt met schuiven tussen de afbeeldingen, worden ze 'uitgelijnd' op een opgegeven positie. Met snappunten maakt het de ervaring van het bladeren door afbeeldingen veel schoner en responsief.

Scrollen met één snap-punt

InteractionTracker en InertiaModifiers

Wanneer u aangepaste manipulatie-ervaringen bouwt met InteractionTracker, kunt u snap point motion-ervaringen maken door gebruik te maken van InertiaModifiers. InertiaModifiers zijn in wezen een manier om te definiëren waar of hoe InteractionTracker de bestemming bereikt bij het invoeren van de status Inertia. U kunt InertiaModifiers toepassen om de X- of Y-positie of schaaleigenschappen van InteractionTracker te beïnvloeden.

Er zijn 3 soorten InertiaModifiers:

  • InteractionTrackerInertiaRestingValue – een manier om de uiteindelijke rustpositie na een interactie of programmatische snelheid te wijzigen. Een vooraf gedefinieerde beweging brengt InteractionTracker naar die positie.
  • InteractionTrackerInertiaMotion – een manier om een specifieke beweging te definiëren die InteractionTracker zal uitvoeren na een interactie of programmatische snelheid. De definitieve positie wordt afgeleid van deze motie.
  • InteractionTrackerInertiaNaturalMotion – een manier om de uiteindelijke rustpositie na een interactie of programmatische snelheid te definiëren, maar met een op fysica gebaseerde animatie (NaturalMotionAnimation).

Bij het invoeren van Inertia evalueert InteractionTracker elk van de InertiaModifiers die eraan zijn toegewezen en bepaalt of een van deze van toepassing is. Dit betekent dat u meerdere InertiaModifiers kunt maken en toewijzen aan een InteractionTracker. Maar wanneer u elk definieert, moet u het volgende doen:

  1. Definieer de voorwaarde: een expressie die de voorwaardelijke instructie definieert wanneer deze specifieke InertiaModifier moet plaatsvinden. Dit vereist vaak het bekijken van de NaturalRestingPosition van de InteractionTracker (bestemming bij standaard Inertia).
  2. Definieer de RestingValue/Motion/NaturalMotion: definieer de werkelijke Resting Value Expression, Motion Expression of NaturalMotionAnimation die plaatsvindt wanneer aan de voorwaarde wordt voldaan.

Opmerking

Het voorwaardeaspect van de InertiaModifiers wordt slechts één keer geëvalueerd wanneer InteractionTracker Inertia binnenkomt. Voor InertiaMotion wordt de bewegingsexpressie echter alleen geëvalueerd voor elk frame voor de modifier waarvan de voorwaarde waar is.

Voorbeeld

Laten we nu eens kijken hoe u InertiaModifiers kunt gebruiken om een aantal snappuntervaringen te maken om het scrollende canvas van afbeeldingen opnieuw te maken. In dit voorbeeld is elke manipulatie bedoeld om mogelijk door een enkele afbeelding te navigeren. Dit wordt vaak aangeduid als 'Single Mandatory Snap Points'.

Laten we beginnen met het instellen van InteractionTracker, VisualInteractionSource en de expressie die de positie van InteractionTracker gebruikt.

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

Vervolgens, omdat een enkel verplicht uitlijnpuntgedrag de inhoud omhoog of omlaag zal verplaatsen, heb je twee verschillende inertieaanpassingen nodig: een die de schuifbare inhoud omhoog verplaatst en een die de inhoud omlaag verplaatst.

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

Of er omhoog of omlaag gesnapt wordt, wordt bepaald op basis van waar InteractionTracker natuurlijk terecht zou komen ten opzichte van de snap-afstand – de afstand tussen de snap-locaties. Als u voorbij het middenpunt bent, dan naar beneden klikken, anders naar boven klikken. (In dit voorbeeld slaat u de uitlijnafstand op in een 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);

Dit diagram geeft een visuele beschrijving van de logica die zich voordoet:

Traagheidswijzigingsdiagram

Nu hoeft u alleen de rustwaarden voor elke InertiaModifier te definiëren: verplaats de positie van de InteractionTracker naar de vorige of volgende uitlijnpositie.

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

Voeg tot slot de InertiaModifiers toe aan InteractionTracker. Als InteractionTracker nu in de InertiaState komt, controleert het de voorwaarden van uw InertiaModifiers om te bepalen of de positie moet worden aangepast.

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