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


Анимации на основе указателей

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

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

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

Зачем создавать интерфейсы на основе позиций указателя?

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

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

Некоторыми примерами могут служить:

  • Анимация позиции в центре внимания для выполнения курсора

    Пример указателя в центре внимания

  • Поворот изображения на основе положения указателя

    Пример поворота указателя

Использование PointerPositionPropertySet

Эти возможности можно создать с помощью PointerPositionPropertySet. Этот набор свойств создается для uiElement для поддержания позиции указателя, пока UIElement положительно тестируется. Значение позиции относительно координат пользовательского элемента UIElement (позиция <0,0> — верхний левый угол uiElement). Затем можно использовать это свойство, заданное в анимации, чтобы управлять движением другого свойства.

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

Общие шаги по началу работы:

  1. Определите uiElement, в котором вы хотите отслеживать положение указателя.
  2. Доступ к PointerPositionPropertySet с помощью ElementCompositionPreview.
  3. Создайте ВыражениеAnimation, ссылающееся на свойство Position в PropertySet.
    • Не забудьте задать эталонный параметр!
  4. Нацелите свойство CompositionObject с помощью ExpressionAnimation.

Примечание.

Рекомендуется назначить СвойствоSet, возвращаемое методом GetPointerPositionPropertySet, переменной класса. Это гарантирует, что набор свойств не очищается сборкой мусора и поэтому не влияет на выражениеAnimation, на который он ссылается. ExpressionAnimations не поддерживает сильную ссылку на какие-либо объекты, используемые в уравнении.

Пример

Рассмотрим пример, в котором мы используем положение наведения указателя мыши и пера для динамического поворота изображения.

Пример поворота указателя

Изображение — это UIElement, поэтому сначала давайте получим ссылку на PointerPositionPropertySet.

_pointerPositionPropSet = ElementCompositionPreview.GetPointerPositionPropertySet(UIElement element);

В этом примере у вас есть два выражения:

  • Выражение, в котором изображение поворачивается на основе далекого указателя находится от центра изображения. Чем дальше, тем больше поворота.
  • Выражение, в котором ось поворота изменяется на основе положения указателя. Вы хотите, чтобы ось поворота была перпендикулярной к вектору позиции.

Здесь вы определяете два выражения, один из них предназначен для свойства RotationAngle и другого свойства RotationAxis. Вы ссылаетесь на PointerPositionPropertySet, как и на любой другой набор свойств.

В этом примере вы создаете выражения с помощью классов ExpressionBuilder .

// using EF = ExpressionBuilder.ExpressionFunctions;
// || DEFINE THE EXPRESSION FOR THE ROTATION ANGLE ||
var hoverPosition = _pointerPositionPropSet.GetSpecializedReference
<PointerPositionPropertySetReferenceNode>().Position;
var angleExpressionNode =
EF.Conditional(
 hoverPosition == new Vector3(0, 0, 0),
 ExpressionValues.CurrentValue.CreateScalarCurrentValue(),
 35 * ((EF.Clamp(EF.Distance(center, hoverPosition), 0, distanceToCenter) % distanceToCenter) / distanceToCenter));
_tiltVisual.StartAnimation("RotationAngleInDegrees", angleExpressionNode);

// || DEFINE THE EXPRESSION FOR THE ROTATION AXIS ||
var axisAngleExpressionNode = EF.Vector3(
-(hoverPosition.Y - center.Y) * EF.Conditional(hoverPosition.Y == center.Y, 0, 1),
 (hoverPosition.X - center.X) * EF.Conditional(hoverPosition.X == center.X, 0, 1),
 0);
_tiltVisual.StartAnimation("RotationAxis", axisAngleExpressionNode);

См. также