Interacciones de lápiz y comentarios hápticos (táctiles)

Windows ha admitido desde hace mucho tiempo los lápices digitales que permiten a los usuarios interactuar con sus dispositivos de forma natural, directa y expresar su creatividad a través de experiencias enriquecidas de escritura y dibujo mediante la entrada de lápiz digital.

Con Windows 11, se introduce una nueva funcionalidad que hace que la experiencia del lápiz digital sea aún más natural y atractiva: cuando se usa un lápiz que admite "comentarios hápticos", los usuarios realmente pueden sentir que el lápiz interactúa de forma táctil con la interfaz de usuario (UI) de una aplicación.

Nota:

Al hacer referencia a esta nueva característica, se usa "háptico" en todas las API de desarrollador y la documentación relacionada, mientras que "táctil" es el nombre descriptivo que se presenta a los usuarios para establecer preferencias de comentarios en la configuración de Windows.

Las experiencias de comentarios hápticos que se admiten en Windows 11 incluyen comentarios de entrada manuscrita y comentarios de interacción:

  • Los comentarios de entrada manuscrita simulan la sensación de varios tipos de escritura o herramientas de dibujo (como lápiz, marcador, lápiz, resaltador, etc.) a través de vibraciones continuas mientras el lápiz está en contacto con la pantalla. De forma predeterminada, la Plataforma Windows Ink admite comentarios hápticos para todas las herramientas de dibujo (en este tema se explica cómo proporcionar una solución de entrada manuscrita personalizada más allá de la admitida por Windows Ink).
  • Los comentarios de interacción, por otro lado, son comentarios directos basados en acciones clave del usuario, como mantener el puntero sobre o hacer clic en un botón, responder a la finalización de una acción o para atraer la atención del usuario.

Normalmente, se requieren cinco pasos para admitir completamente los comentarios hápticos:

  • Detecte la entrada del lápiz.
  • Determine si el lápiz actual y el dispositivo admiten comentarios hápticos y, si es así, qué características de comentarios hápticos admite.
  • Decida la señal de comentarios hápticos que se va a enviar.
  • Envíe los comentarios hápticos.
  • Detener los comentarios hápticos

Detección de la entrada del lápiz

Para detectar y aislar la entrada del lápiz, primero debe registrarse para el evento PointerEntered y, a continuación, comprobar si PointerDeviceType es un lápiz.

En el código siguiente se muestra cómo comprobar el tipo de dispositivo de puntero dentro de un evento PointerEntered. En este ejemplo, si la entrada no procede de un lápiz, simplemente se devuelve desde el controlador de eventos. De lo contrario, comprobamos las funcionalidades del lápiz y configuramos los comentarios hápticos.


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

Determinar la compatibilidad con comentarios hápticos

No todos los lápices y digitalizadores admiten comentarios hápticos, y los lápices que no admiten necesariamente todas las características de comentarios hápticos descritas en este tema. Por lo tanto, es importante confirmar mediante programación qué características son compatibles con el lápiz activo.

En una continuación del ejemplo anterior, se muestra cómo comprobar si el lápiz activo admite comentarios hápticos.

Primero intentamos recuperar un objeto PenDevice del pointerId actual. Si no se puede obtener un PenDevice , simplemente regresamos del controlador de eventos.

Si se obtuvo un PenDevice , se prueba si admite una propiedad SimpleHapticsController . Si no es así, simplemente regresamos del controlador de eventos.

// 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 recuperado en el ejemplo anterior se usa en ejemplos posteriores para consultar funcionalidades hápticas y enviar o detener comentarios hápticos.

Nota

Si va a compilar aplicaciones con la versión preliminar 1.0 de SDK de Aplicaciones para Windows, puede usar la interoperabilidad PenDevice (PenDeviceInterop.FromPointerPoint(PointerPoint)) para acceder al sistema PenDevice.

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

En las secciones siguientes se describen las características de comentarios que deben admitir los lápices hápticos, así como las que son opcionales. Normalmente, un tipo de comentarios hápticos requerido se puede usar como reserva en lugar de una característica opcional.

Formas de onda de entrada manuscrita

Las formas de onda de entrada manuscrita se reproducen continuamente mientras el lápiz está en contacto con la pantalla e intentan simular la sensación de varias herramientas de escritura o dibujo.

Característica Descripción Obligatorio u opcional
Forma de onda InkContinous Simula la sensación de la entrada manuscrita con un lápiz de punta de bola físico. Esta es la reserva predeterminada cuando una forma de onda manuscrita no es compatible con un lápiz háptico. Obligatorio
Forma de onda brushContinuous Señal háptica continua cuando el usuario selecciona pincel como herramienta de entrada manuscrita. Opcionales
Forma de onda chiselMarkerContinuous Señal háptica continua cuando el usuario selecciona marcador o resaltador de chisel como herramienta de entrada manuscrita. Opcionales
Forma de onda EraserContinuous Señal háptica continua cuando el usuario selecciona borrador como herramienta de entrada manuscrita. Opcionales
Forma de onda GalaxyContinuous
(la guía de implementación y documentación de HID hace referencia a esta forma de onda como SparkleContinuous)
Señal háptica continua para herramientas de tinta especiales, como un pincel multicolor. Opcionales
Forma de onda markerContinuous Señal háptica continua cuando el usuario selecciona marcador como herramienta de entrada manuscrita. Opcionales
Forma de onda PencilContinuous Señal háptica continua cuando el usuario selecciona lápiz como herramienta de entrada manuscrita. Opcionales

Formas de onda de interacción

Las formas de onda de interacción suelen ser cortas (excepciones indicadas en la tabla siguiente), formas de onda de comentarios directas generadas a petición para confirmar acciones clave, como mantener el puntero sobre o hacer clic en un botón, responder a la finalización de una acción o para atraer la atención del usuario.

Característica Descripción Obligatorio u opcional
Hacer clic en forma de onda Comentarios cortos de "clic". Esta es la reserva predeterminada cuando una forma de onda de interacción seleccionada por la aplicación no es compatible con un lápiz háptico. Obligatorio
Forma de onda de error Señal fuerte para alertar al usuario de que se ha producido un error en una acción o que se ha producido un error. Opcionales
Forma de onda de desplazamiento Indica que el usuario ha empezado a mantener el puntero sobre un elemento interactivo de la interfaz de usuario. Opcionales
Presionar forma de onda Indica cuándo un usuario presiona un elemento de interfaz de usuario interactivo en una acción incremental (consulte Release). Opcionales
Forma de onda de liberación Indica cuándo un usuario libera un elemento de interfaz de usuario interactivo en una acción incremental (vea Presionar). Opcionales
Forma de onda correcta Señal fuerte para alertar al usuario de que una acción se realizó correctamente. Opcionales
Forma de onda BuzzContinuous Sensación de zumbido continuo. Opcionales
Forma de onda RumbleContinuous Sensación continua de saltos de tamaño. Opcionales

Personalizaciones de comentarios hápticos

Algunos lápices hápticos pueden admitir las siguientes personalizaciones.

Característica Descripción Obligatorio u opcional
Intensidad Establece la intensidad de la señal háptica. Opcionales
Recuento de reproducción Repite una señal háptica un número especificado de veces. Opcionales
Intervalo de pausa de reproducción Establece el tiempo entre cada reproducción repetida de la señal háptica. Opcionales
Duración de la reproducción Establece el intervalo de tiempo que se reproduce una señal háptica. Opcionales

Comprobación de la compatibilidad con la configuración personalizada

Para comprobar la intensidad, el recuento de reproducciones, el intervalo de pausa de reproducción y la duración de la reproducción, use las siguientes propiedades de SimpleHapticsController:

Enviar y detener la entrada manuscrita de comentarios hápticos

Utilice el método SendHapticFeedback del objeto SimpleHapticsController para pasar formas de onda manuscritas al lápiz del usuario. Este método permite pasar una forma de onda o una forma de onda con un valor de intensidad personalizado (consulte Personalizar comentarios hápticos).

Llama a SendHapticFeedback y pasa una forma de onda de entrada manuscrita para configurar el lápiz para empezar a reproducir esa forma de onda tan pronto como la punta del lápiz toque en cualquier parte de la pantalla. La forma de onda continuará jugando hasta que se levante el lápiz o se llame a StopFeedback , lo que ocurra primero. Se recomienda hacerlo en el controlador de eventos PointerEntered para el elemento en el que desea que se reproduzca la háptica. Por ejemplo, una aplicación con una implementación de entrada manuscrita personalizada lo haría en el método PointerEntered de su lienzo de entrada manuscrita.

Para recuperar la forma de onda de entrada manuscrita deseada, debe recorrer en iteración la colección SupportedFeedback de SimpleHapticsController, asegurándose de que es compatible con el lápiz activo.

Si no se admite, puede optar por no reproducir nada en absoluto o revertir a la forma de onda InkContinuous , ya que se garantiza que se admita.

En el ejemplo siguiente, intentamos enviar la forma de onda BrushContinuous (pero revertir a InkContinuous si brushContinuous no se admite).

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

Es importante que también detenga los comentarios hápticos cuando el puntero asociado salga del elemento que registró para recibir comentarios hápticos. De lo contrario, la forma de onda seguirá intentando reproducirse en el lápiz activo.

Nota:

Opcionalmente, algunos lápices pueden detener hápticos por sí mismos cuando el lápiz sale del intervalo de la pantalla. Sin embargo, no es necesario que todos los lápices lo hagan, por lo que las aplicaciones siempre deben detener explícitamente los comentarios hápticos, como se describe aquí.

Para detener los comentarios hápticos en un elemento, regístrese para el evento PointerExited en el mismo elemento que registró el controlador PointerEntered que envió la señal háptica. En ese controlador de eventos salido, llame a StopFeedback como se muestra aquí.

hapticsController.StopFeedback();

Envío y detención de comentarios de interacción

Enviar comentarios de interacción es bastante similar al envío de comentarios de entrada manuscrita.

Utilice el método SendHapticFeedback del objeto SimpleHapticsController para pasar formas de onda de interacción al lápiz del usuario. Este método permite pasar una forma de onda o una forma de onda con un valor de intensidad personalizado (consulte Personalizar comentarios hápticos).

Llama a SendHapticFeedback y pasa una forma de onda de entrada manuscrita para configurar el lápiz para empezar a reproducir esa forma de onda inmediatamente en función de alguna interacción dentro de la aplicación (en lugar de cuando la punta del lápiz toca la pantalla para enviar comentarios de entrada manuscrita).

Cuando se usa cualquiera de las formas de onda de interacción no continuas, no es necesario realizar una llamada StopFeedback correspondiente. Todavía tiene que llamar a StopFeedback para las formas de onda de interacción continuas.

Nota

El envío de una forma de onda de interacción cuando se reproduce una forma de onda de entrada manuscrita interrumpirá temporalmente la forma de onda de entrada manuscrita. La forma de onda de entrada manuscrita se reanudará cuando se detenga la forma de onda de interacción.

Para recuperar la forma de onda de interacción deseada, debe recorrer en iteración la colección SupportedFeedback de SimpleHapticsController, asegurándose de que es compatible con el lápiz activo.

Si no se admite, puede optar por no reproducir nada en absoluto o revertir a la forma de onda Click , ya que se garantiza que se admita.

En el ejemplo siguiente, intentamos enviar la forma de onda Error (pero recurrir a Click if Error is not supported).

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

Personalización de comentarios hápticos

Hay tres maneras de personalizar los comentarios hápticos. La primera es compatible con los comentarios de entrada manuscrita y interacción, mientras que la segunda y la tercera solo son compatibles con los comentarios de interacción.

  1. Ajuste la intensidad de los comentarios en relación con el valor de intensidad máxima del sistema. Para ello, primero debe comprobar que SimpleHapticsController admite establecer la intensidad y, a continuación, llamar a SendHapticFeedback con el valor deseado Intensity .

    if (hapticsController.IsIntensitySupported) 
    {
        foreach (var waveform in hapticsController.SupportedFeedback)
        {
            if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Click)
            {
                double intensity = 0.75;
                hapticsController.SendHapticFeedback(waveform, intensity);
            }
        }
    }
    
  2. Repita la señal háptica un número especificado de veces. Para ello, primero debe comprobar que SimpleHapticsController admite establecer la intensidad y, a continuación, llamar a SendHapticFeedbackForPlayCount con el valor de recuento deseado. También puede establecer la intensidad y el intervalo de pausa de reproducción.

    Nota

    Si SimpleHapticsController no admite establecer la intensidad o el intervalo de pausa de reproducción, se omitirán los valores proporcionados.

    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. Establezca la duración de la señal háptica. Para ello, primero debe comprobar que SimpleHapticsController admite establecer la duración de la reproducción y, a continuación, llamar a SendHapticFeedbackForDuration con el valor de intervalo de tiempo deseado. También puedes establecer la intensidad.

    Nota

    Si SimpleHapticsController no admite establecer la intensidad, se omitirá el valor proporcionado.

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

Ejemplos

Consulte el ejemplo pen háptico para ver ejemplos prácticos de la siguiente funcionalidad: