Поделиться через


Создание точек оснастки с модификаторами инерции

В этой статье мы подробно рассмотрим, как использовать функцию "Инерционный модификатор ВзаимодействияTracker" для создания возможностей перемещения, которые привязываются к указанной точке.

Необходимые компоненты

Здесь предполагается, что вы знакомы с понятиями, описанными в следующих статьях:

Что такое точки привязки и почему они полезны?

При создании пользовательских возможностей манипуляций иногда полезно создавать специализированные точки положения в прокручиваемом или масштабируемом холсте, на который Будет всегда приходить взаимодействиеTracker. Они часто называются точками привязки.

Обратите внимание, что в следующем примере прокрутка может оставить пользовательский интерфейс в неловком положении между различными изображениями:

Прокрутка без точек привязки

При добавлении точек оснастки при остановке прокрутки между изображениями они "прикрепляются" к указанной позиции. С точками оснастки это делает процесс прокрутки изображений гораздо более чистым и более адаптивным.

Прокрутка с помощью одной точки привязки

InteractionTracker и ИнерционныеModifierы

При создании настраиваемых операций с помощью InteractionTracker можно создавать интерфейсы движения точек оснастки, используя инерционные модификаторы. Инерционныеmodifierы по сути являются способом определения того, где или как InteractionTracker достигает своего назначения при входе в состояние инерции. Можно применить инерционные модификаторы, чтобы повлиять на положение X или Y или свойства Scale объекта InteractionTracker.

Существует 3 типа инерционных модификаторов:

  • InteractionTrackerInertiaRestingValue — способ изменить окончательное положение отдыха после взаимодействия или программной скорости. Предопределенное движение будет принимать InteractionTracker в эту позицию.
  • InteractionTrackerInertiaMotion — способ определения определенного взаимодействия с движениемTracker будет выполняться после взаимодействия или программной скорости. Окончательное положение будет производным от этого движения.
  • InteractionTrackerInertiaNaturalMotion — способ определить окончательную позицию отдыха после взаимодействия или программной скорости, но с анимацией на основе физики (NaturalMotionAnimation).

При вводе инерции InteractionTracker оценивает каждый из назначенных ему инерционных модификаторов и определяет, применяются ли какие-либо из них. Это означает, что вы можете создать и назначить несколько инерционныхmodifiers в элементу InteractionTracker, но при определении каждого из них необходимо выполнить следующие действия:

  1. Определите условие — выражение, определяющее условную инструкцию при выполнении этого конкретного инерционного модификатора. Для этого часто требуется взглянуть на NaturalRestingPosition в InteractionTracker (назначение с учетом инерции по умолчанию).
  2. Определите значение RestingValue/Motion/NaturalMotion— определите фактическое выражение значения resting, выражение движения или NaturalMotionAnimation, которое происходит при выполнении условия.

Примечание.

Аспект условия инерционныхmodifiers оценивается только один раз, когда InteractionTracker входит в инерцию. Однако только для инерции выражение движения вычисляется каждый кадр для модификатора, условие которого верно.

Пример

Теперь давайте посмотрим, как можно использовать ИнерционныеModifierы для создания некоторых возможностей точки привязки для воссоздания холста прокрутки изображений. В этом примере каждая манипуляция предназначена для потенциального перемещения по одному изображению— это часто называется одной обязательной точкой привязки.

Начнем с настройки InteractionTracker, VisualInteractionSource и выражения, которые будут использовать позицию 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);
}

Далее, поскольку поведение одной обязательной точки оснастки будет перемещать содержимое вверх или вниз, вам потребуется два разных модификатора инерции: один, который перемещает содержимое прокрутки вверх, и тот, который перемещает его вниз.

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

Независимо от того, следует ли оснастки вверх или вниз определяться на основе того, где ВзаимодействиеTracker естественно приземлится в пределах расстояния от оснастки — расстояние между расположениями оснастки. Если прошло полпути, то прикрепите вниз, в противном случае оснастки вверх. (В этом примере вы сохраняете расстояние от оснастки в 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);

Эта схема содержит визуальное описание логики, которая происходит:

Схема модификатора инерции

Теперь необходимо просто определить остальные значения для каждого инерционного модификатора: переместите позицию InteractionTracker на предыдущую позицию оснастки или следующую.

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

Наконец, добавьте инерционныеmodifierы в InteractionTracker. Теперь, когда InteractionTracker входит в это инерционное состояние, он проверяет условия инерционныхmodifiers, чтобы узнать, следует ли изменить его позицию.

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