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


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

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

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

Замечание

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

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

  • Обратная связь рукописного ввода имитирует ощущение различных типов инструментов для письма или рисования (например, пера, маркера, карандаша, текстовыделителя и т. д.) с помощью непрерывных вибраций во время контакта пера с экраном. По умолчанию платформа Windows Ink Platform поддерживает тактильную обратную связь для всех инструментов для рисования (в этой теме рассматривается, как обеспечить кастомное решение для рукописного ввода сверх тех, что поддерживаются в 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, полученный в предыдущем примере, используется в последующих примерах для запроса возможностей тактильной обратной связи и передачи и прекращения тактильной обратной связи.

Замечание

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

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

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

Нанесение чернилами формы волн

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Если поддержка отсутствует, вы можете либо вообще ничего не воспроизводить, либо переключиться на форму волны 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 для непрерывных волновых форм взаимодействия.

Замечание

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

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

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

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

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

Примеры

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

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