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


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

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

Необходимые условия

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

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

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

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

Ниже приведены некоторые примеры:

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

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

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

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

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

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

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

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

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

Замечание

Рекомендуется присвоить PropertySet, возвращаемый методом GetPointerPositionPropertySet, переменной класса. Это гарантирует, что набор свойств не будет удален сборщиком мусора и, следовательно, не окажет никакого влияния на ExpressionAnimation, в котором он используется. 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);

См. также