Sdílet prostřednictvím


Vytvořte body záchytu pomocí modifikátorů inerce

V tomto článku se podrobněji podíváme na to, jak pomocí funkce InertiaModifier modulu InteractionTracker vytvořit pohybové zážitky, které se přichytí k určenému bodu v aplikaci WinUI.

V aplikacích InteractionTracker WinUI a související typy modifikátoru inertia jsou v Microsoft.UI.Composition.Interactions oboru názvů.

Předpoklady

Tady předpokládáme, že znáte koncepty, které jsou popsány v těchto článcích:

Co jsou body přichytávání a proč jsou prospěšné?

Při vytváření vlastních prostředí pro manipulaci je někdy užitečné vytvořit specializované pozicní body na plátně, které lze posouvat a přibližovat, na které se InteractionTracker vždy zastaví. Tyto body se často označují jako body přichycení.

Všimněte si v následujícím příkladu, jak může posouvání zanechat uživatelské rozhraní v nepřehledné pozici mezi různými obrázky:

Posouvání bez bodů přichycení

Pokud přidáte body přichycení, když se mezi obrázky přestanete posouvat, "přichytí" k zadané pozici. Díky záchytným bodům je zážitek z posouvání obrázků mnohem přehlednější a citlivější.

Posouvání s jedním bodem přichycení

InteractionTracker a InertiaModifiers

Při sestavování přizpůsobených prostředí pro manipulaci s InteractionTrackerem můžete vytvářet pohybové zážitky bodů přichycení pomocí InertiaModifiers. InertiaModifiers jsou v podstatě způsob, jak definovat, kde nebo jak InteractionTracker dosáhne cíle při vstupu do stavu inertia. InertiaModifiers můžete použít k ovlivnění vlastností pozice X nebo Y nebo vlastnosti měřítka InteractionTrackeru.

Existují tři typy inertiaModifiers:

  • InteractionTrackerInertiaRestingValue – způsob, jak změnit konečnou pozici odpočinku po interakci nebo programové rychlosti. Předdefinovaný pohyb převezme InteractionTracker na danou pozici.
  • InteractionTrackerInertiaMotion – způsob, jak definovat konkrétní pohyb, který bude InteractionTracker provádět po interakci nebo programově určené rychlosti. Konečná pozice bude odvozena z tohoto pohybu.
  • InteractionTrackerInertiaNaturalMotion – způsob, jak určit konečnou klidovou polohu po interakci nebo programové rychlosti, ale s animací založenou na fyzice (NaturalMotionAnimation).

Při vstupu do Inertia nástroj InteractionTracker vyhodnotí každý z InertiaModifiers, které jsou k němu přiřazeny, a určí, zda se některý z nich použije. To znamená, že můžete vytvořit a přiřadit více inertiaModifiers k InteractionTracker. Při definování každého z nich ale musíte udělat toto:

  1. Definujte podmínku – výraz, který definuje podmíněný příkaz, když se má provést tento konkrétní InertiaModifier. To často vyžaduje pohled na NaturalRestingPosition InteractionTrackeru vzhledem k výchozí setrvačnosti.
  2. Definujte RestingValue/Motion/NaturalMotion – určete skutečný výraz odpočinkové hodnoty, pohybový výraz nebo NaturalMotionAnimation, který se použije při splnění podmínky.

Poznámka:

Aspekt podmínky u InertiaModifiers se vyhodnocuje pouze jednou, když InteractionTracker vstoupí do Inertia. Nicméně pouze pro InertiaMotion je výraz pohybu vyhodnocen pro každý snímek u modifikátoru, jehož podmínka je pravdivá.

Příklad

Teď se podíváme, jak můžete pomocí InertiaModifiers vytvořit zážitek s body přichycení pro rekonstrukci posuvného plátna obrázků. V tomto příkladu se každá manipulace má potenciálně pohybovat jedním obrázkem – to se často označuje jako jednoduché povinné body přichycení.

Začněme nastavením InteractionTrackeru, VisualInteractionSource a výrazu, který bude využívat pozici InteractionTrackeru.

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

V dalším kroku, protože chování jediného povinného přichycení buď přesune obsah nahoru, nebo dolů, budete potřebovat dva různé modifikátory setrvačnosti: jeden, který přesune posunovatelný obsah nahoru, a jeden, který ho přesune dolů.

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

Určuje se, jestli se má přichytit nahoru nebo dolů podle toho, kde by InteractionTracker přirozeně skončil vzhledem k vzdálenosti přichycení – vzdálenost mezi body přichycení. Pokud je za polovinou, pak zaklapněte dolů, jinak zaklapněte nahoru. (V tomto příkladu uložíte vzdálenost přichycení v 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);

Tento diagram poskytuje vizuální popis logiky, která se děje:

Diagram modifikátoru nečinnosti

Teď stačí definovat klidové hodnoty pro každý InertiaModifier: přesuňte buď pozici InteractionTracker na předchozí snímací pozici nebo na další snímací pozici.

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

Nakonec přidejte inertiaModifiers do InteractionTracker. Když teď InteractionTracker vstoupí do stavu InertiaState, zkontroluje podmínky inertiaModifiers a zjistí, jestli má být změněna jeho pozice.

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