Взаимодействие с пером и тактильная обратная связь

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

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

Примечание

При обращении к этой новой функции "тактильный" используется в API разработчика и связанной документации, а "тактильный" — это понятное имя, предоставляемое пользователям для настройки настроек обратной связи в параметрах Windows.

Поддержка тактильной обратной связи в Windows 11 включает в себя обратную связь от рукописного ввода и обратную связь о взаимодействии:

  • Обратная связь с рукописным вводом имитирует ощущение различных видов инструментов для письма или рисования (например, пера, маркера, карандаша, маркера и т. д.) с помощью непрерывных вибраций, когда перо находится в контакте с экраном. По умолчанию платформа Windows Ink поддерживает тактильную обратную связь для всех средств рисования (в этом разделе описывается, как предоставить пользовательское решение для рукописного ввода, не поддерживаемое Windows Ink).
  • С другой стороны, обратная связь о взаимодействии — это прямая обратная связь, основанная на ключевых действиях пользователя, таких как наведение указателя мыши или нажатие кнопки, реагирование на выполнение действия или привлечение внимания пользователя.

Как правило, для полной поддержки тактильной обратной связи требуется пять шагов:

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

Обнаружение входных данных с помощью пера

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

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


private void InputObserver_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    ...
    
    // If the current Pointer device is not a pen, exit.
    if (e.Pointer.PointerDeviceType != PointerDeviceType.Pen) 
    {
       return;
    }
    
    ...    
}

Определение поддержки тактильной обратной связи

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

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

Сначала мы попытаемся получить объект PenDevice из текущего pointerId. Если не удается получить PenDevice , мы просто возвращаем данные из обработчика событий.

Если был получен объект PenDevice , мы проверяем, поддерживает ли он свойство SimpleHapticsController . В противном случае мы снова просто возвращаем данные из обработчика событий.

// Attempt to retrieve the PenDevice from the current PointerId.
penDevice = PenDevice.GetFromPointerId(e.Pointer.PointerId);

// If a PenDevice cannot be retrieved based on the PointerId, it does not support 
// advanced pen features, such as haptic feedback. 
if (penDevice == null)
{
    return;
}

// Check to see if the current PenDevice supports haptic feedback by seeing if it 
// has a SimpleHapticsController.
hapticsController = penDevice.SimpleHapticsController;
if (hapticsController == null)
{
    return;
}

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

Примечание

Если вы создаете приложения с помощью предварительной версии Windows App SDK 1.0, вы можете использовать взаимодействие PenDevice (PenDeviceInterop.FromPointerPoint(PointerPoint)) для доступа к системе PenDevice.

private void InputObserver_PointerEntered(PointerInputObserver sender, PointerEventArgs args)
{
    var penDevice = PenDeviceInterop.PenDeviceFromPointerPoint(args.CurrentPoint);
}

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

Рукописный ввод волновых форм

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

Функция Описание Обязательный или необязательный
InkContinous waveform Имитирует ощущение рукописного ввода с помощью физической шариковой ручки. Это резервный вариант по умолчанию, когда тактильное перо не поддерживает форму рукописного ввода. Обязательно
BrushContinuous waveform Непрерывный тактильные сигнал, когда пользователь выбирает кисть в качестве инструмента рукописного ввода. Необязательно
ChiselMarkerContinuous waveform Непрерывный тактильной сигнал, когда пользователь выбирает маркер или маркер долота в качестве инструмента рукописного ввода. Необязательно
Ластик Непрерывная форма волны Непрерывный тактильной сигнал, когда пользователь выбирает ластик в качестве инструмента рукописного ввода. Необязательно
Форма волны GalaxyContinuous
(В документации и руководстве по реализации HID эта форма волн называется SparkleContinuous)
Непрерывный тактильные сигналы для специальных инструментов рукописного ввода, таких как разноцветная кисть. Необязательно
МаркерСдерная форма волны Непрерывный тактильные сигналы, когда пользователь выбирает маркер в качестве инструмента рукописного ввода. Необязательно
Карандаш Непрерывная форма волны Непрерывный тактильные сигналы, когда пользователь выбирает карандаш в качестве инструмента рукописного ввода. Необязательно

Формы волн взаимодействия

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

Функция Описание Обязательный или необязательный
Щелкните форму волны Краткий отзыв по щелчку. Это откат по умолчанию, когда форма взаимодействия, выбранная приложением, не поддерживается тактильной ручкой. Обязательно
Форма волны ошибки Сильный сигнал для оповещения пользователя о сбое действия или об ошибке. Необязательно
Форма волны при наведении указателя мыши Указывает, что пользователь начал наведение указателя мыши на интерактивный элемент пользовательского интерфейса. Необязательно
Форма нажатия Указывает, когда пользователь нажимает интерактивный элемент пользовательского интерфейса в добавочном действии (см. выпуск). Необязательно
Форма выпуска Указывает, когда пользователь отпускает интерактивный элемент пользовательского интерфейса в добавочном действии (см. раздел Нажатие). Необязательно
Форма успешной волны Сильный сигнал для оповещения пользователя об успешном выполнении действия. Необязательно
BuzzContinuous waveform Непрерывное жужжание ощущение. Необязательно
RumbleContinuous waveform Непрерывное ощущение грохония. Необязательно

Настройки тактильной обратной связи

Некоторые тактильные ручки могут поддерживать следующие настройки.

Функция Описание Обязательный или необязательный
Интенсивность Задает интенсивность тактильной передачи сигнала. Необязательно
Число воспроизведения Повторяет тактильные сигналы заданное количество раз. Необязательно
Интервал паузы воспроизведения Задает время между каждым повторяющимся воспроизведением тактильной передачи сигнала. Необязательно
Длительность воспроизведения Задает интервал времени воспроизведения тактильной передачи сигнала. Необязательно

Проверка поддержки пользовательских параметров

Чтобы проверка для поддержки "Интенсивность", "Число воспроизведения", "Интервал паузы воспроизведения" и "Длительность воспроизведения", используйте следующие свойства SimpleHapticsController:

Отправка и остановка рукописного ввода тактильной обратной связи

Используйте метод SendHapticFeedback объекта SimpleHapticsController , чтобы передать рукописные формы волн в перо пользователя. Этот метод поддерживает передачу либо волны, либо обеих форм с настраиваемым значением интенсивности (см . раздел Настройка тактильной обратной связи).

Вызовите SendHapticFeedback и передайте волны рукописного ввода , чтобы настроить перо, чтобы начать воспроизведение этой формы, как только кончик пера касается любого места на экране. Форма волны будет продолжать воспроизводиться до тех пор, пока перо не будет снято или не будет вызван StopFeedback , в зависимости от того, что произойдет первым. Рекомендуется сделать это в обработчике событий PointerEntered для элемента, в котором требуется воспроизвести тактильные элементы. Например, приложение с пользовательской реализацией рукописного ввода будет делать это в методе PointerEntered холста рукописного ввода.

Чтобы получить требуемую форму рукописного ввода, необходимо выполнить итерацию по коллекции SupportedFeedbackэлемента SimpleHapticsController, чтобы убедиться, что она поддерживается активным пером.

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

В следующем примере мы пытаемся отправить волновую форму BrushContinuous (но вернитесь к InkContinuous, если BrushContinuous не поддерживается).

SimpleHapticsControllerFeedback currentWaveform;

// Attempt to set the currentWaveform to BrushContinuous.
foreach (var waveform in hapticsController.SupportedFeedback)
{
    if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.BrushContinuous)
    {
        currentWaveform = waveform;
    }
} 

// If currentWaveform is null, it was not in the SupportedFeedback collection, so instead set 
// the waveform to InkContinuous.
if (currentWaveform == null)
{
    foreach (var waveform in hapticsController.SupportedFeedback)
    {
        if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.InkContinuous)
        {
            currentWaveform = waveform;
        }
    }
}

// Send the currentWaveform 
hapticsController.SendHapticFeedback(currentWaveform);

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

Примечание

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

Чтобы остановить тактильную обратную связь по элементу, зарегистрируйтесь для события PointerExited в том же элементе, что и обработчик PointerEntered, отправляющий тактиленный сигнал. В этом обработчике событий с выходом вызовите StopFeedback , как показано ниже.

hapticsController.StopFeedback();

Отправка и остановка отзывов о взаимодействии

Отправка отзывов о взаимодействии очень похожа на отправку обратной связи от рукописного ввода.

Используйте метод SendHapticFeedback объекта SimpleHapticsController для передачи форм взаимодействия в перо пользователя. Этот метод поддерживает передачу либо волны, либо обеих форм с настраиваемым значением интенсивности (см . раздел Настройка тактильной обратной связи).

Вызовите SendHapticFeedback и передайте волны рукописного ввода , чтобы настроить перо, чтобы начать воспроизведение этой формы волны немедленно на основе некоторого взаимодействия в приложении (вместо того, когда кончик пера касается экрана для обратной связи от рукописного ввода).

При использовании любой из непрестанных форм взаимодействия нет необходимости выполнять соответствующий вызов StopFeedback . Вам по-прежнему нужно вызвать StopFeedback для волновых форм непрерывного взаимодействия.

Примечание

Отправка волновой формы взаимодействия при воспроизведении рукописной волны временно прерывает волновую форму рукописного ввода. Форма рукописного ввода будет возобновлена при остановке формы волны взаимодействия.

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

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

В следующем примере мы пытаемся отправить волновую форму ошибки (но вернитесь к щелчку, если ошибка не поддерживается).

SimpleHapticsControllerFeedback currentWaveform;  

// Attempt to set the currentWaveform to BrushContinuous.
foreach (var waveform in hapticsController.SupportedFeedback)
{
    if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Error)
    {
        currentWaveform = waveform;
    }
} 

// If currentWaveform is null, it was not in the SupportedFeedback collection, so instead set 
// the waveform to Click.
if (currentWaveform == null)
{
    foreach (var waveform in hapticsController.SupportedFeedback)
    {
        if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Click)
        {
            currentWaveform = waveform;
        }
    }
} 

// Send the currentWaveform.
hapticsController.SendHapticFeedback(currentWaveform); 

Настройка тактильной обратной связи

Существует три способа настройки тактильной обратной связи. Первый поддерживается как рукописным вводом, так и обратной связью о взаимодействии, а второй и третий поддерживаются только отзывами о взаимодействии.

  1. Настройте интенсивность обратной связи относительно параметра максимальной интенсивности системы. Для этого необходимо сначала проверка, чтобы убедиться, что SimpleHapticsController поддерживает настройку интенсивности, а затем вызвать SendHapticFeedback с нужным значениемIntensity.

    if (hapticsController.IsIntensitySupported) 
    {
        foreach (var waveform in hapticsController.SupportedFeedback)
        {
            if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Click)
            {
                double intensity = 0.75;
                hapticsController.SendHapticFeedback(waveform, intensity);
            }
        }
    }
    
  2. Повторите тактильные сигналы заданное число раз. Для этого необходимо сначала проверка, чтобы убедиться, что SimpleHapticsController поддерживает настройку интенсивности, а затем вызвать SendHapticFeedbackForPlayCount с нужным значением счетчика. Вы также можете задать как интенсивность, так и интервал паузы воспроизведения.

    Примечание

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

    if (hapticsController.IsPlayCountSupported && hapticsController.IsIntensitySupported && hapticsController.IsReplayPauseIntervalSupported)
    {
        foreach (var waveform in hapticsController.SupportedFeedback)
        {
            if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Click)
            {
                double intensity = 0.75;
                int playCount = 3;
                System.TimeSpan pauseDuration = new System.TimeSpan(1000000);
                hapticsController.SendHapticFeedbackForPlayCount(currentWaveform, intensity, playCount, pauseDuration);
            }
        }
    }
    
  3. Задайте длительность тактильной передачи сигнала. Для этого необходимо сначала проверка, чтобы убедиться, что SimpleHapticsController поддерживает настройку длительности воспроизведения, а затем вызвать SendHapticFeedbackForDuration с нужным значением интервала времени. Вы также можете задать интенсивность.

    Примечание

    Если SimpleHapticsController не поддерживает настройку интенсивности, указанное значение будет игнорироваться.

    if (hapticsController.IsPlayDurationSupported && hapticsController.IsIntensitySupported)
    {
        foreach (var waveform in hapticsController.SupportedFeedback)
        {
            if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.RumbleContinuous)
            {
                double intensity = 0.75;
                System.TimeSpan playDuration = new System.TimeSpan(5000000);
                hapticsController.SendHapticFeedbackForDuration(currentWaveform, intensity, playDuration);
            }
        }
    }
    

Примеры

Примеры работы со следующими функциями см. в примере тактильной ручки:

  • Получение элемента SimpleHapticsController из входных данных пером: переход от PointerId к PenDevice в SimpleHapticsController (требуется перо с тактильной поддержкой и устройство, поддерживающее перо).
  • Проверьте возможности тактильной ручки. SimpleHapticsController предоставляет свойства для аппаратных возможностей пера, включая IsIntensitySupported, IsPlayCountSupported, SupportedFeedback и т. д.
  • Запуск и остановка тактильной обратной связи. Используйте методы SendHapticFeedback и StopFeedback соответствующим образом.
  • Активация тактильной обратной связи: обратная связь как для рукописного ввода, так и для обратной связи о взаимодействии.