Compartilhar via


Interações com caneta e feedback háptico (tátil)

O Windows há muito tem suporte para canetas digitais que permitem que os usuários interajam com seus dispositivos de forma natural e direta e expressem sua criatividade através de experiências ricas de escrita e desenho usando tinta digital.

Com o Windows 11, uma nova funcionalidade está sendo introduzida que torna a experiência de caneta digital ainda mais natural e atraente: ao usar uma caneta que dá suporte a "comentários hápticos", os usuários podem realmente sentir sua caneta interagindo de maneira tátil com a interface do usuário (interface do usuário) de um aplicativo.

Observação

Ao se referir a esse novo recurso, "háptico" é usado em todas as APIs do desenvolvedor e na documentação relacionada, enquanto "tátil" é o nome amigável apresentado aos usuários para definir preferências de feedback nas Configurações do Windows.

As experiências de feedback háptico com suporte no Windows 11 incluem feedback de escrita e feedback de interação:

  • Os feedbacks táteis de escrita simulam a sensação de vários tipos de ferramentas de escrita ou desenho (como caneta, marcador, lápis, marca-texto, etc.) por meio de vibrações contínuas enquanto a caneta está em contato com a tela. Por padrão, a Plataforma Windows Ink dá suporte a comentários hápticos para todas as ferramentas de desenho (este tópico aborda como fornecer uma solução de escrita à tinta personalizada além daquela com suporte do Windows Ink).
  • Os comentários de interação, por outro lado, são comentários diretos com base em ações importantes do usuário, como passar o mouse ou clicar em um botão, responder à conclusão de uma ação ou chamar a atenção do usuário.

Normalmente, cinco etapas são necessárias para dar suporte total a comentários hápticos:

  • Detectar entrada de caneta.
  • Determine se a caneta e o dispositivo atuais dão suporte a feedback háptico e, em caso afirmativo, quais recursos de feedback háptico eles oferecem suporte.
  • Decida sobre o sinal de feedback háptico a ser enviado.
  • Envie os comentários hápticos.
  • Parar os comentários hápticos

Detectar entrada de caneta

Para detectar e isolar a entrada da caneta, primeiro registre-se para o evento PointerEntered e verifique se o PointerDeviceType é uma caneta.

O código a seguir mostra como verificar o tipo de dispositivo de ponteiro dentro de um evento PointerEntered. Para este exemplo, se a entrada não for de uma caneta, simplesmente retornaremos do manipulador de eventos. Caso contrário, verificamos as capacidades da caneta e configuramos o feedback háptico.


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 o suporte para comentários hápticos

Nem todas as canetas e digitalizadores dão suporte a comentários hápticos, e as canetas que fazem isso não necessariamente darão suporte a todos os recursos de comentários hápticos descritos neste tópico. Dessa forma, é importante confirmar programaticamente quais recursos têm suporte na caneta ativa.

Em uma continuação do exemplo anterior, mostramos como verificar se a caneta ativa dá suporte a comentários hápticos.

Primeiro tentamos recuperar um objeto PenDevice do PointerId atual. Se um PenDevice não puder ser obtido, simplesmente retornaremos do manipulador de eventos.

Se um PenDevice foi obtido, testamos se ele dá suporte a uma propriedade SimpleHapticsController . Caso contrário, novamente simplesmente retornaremos do manipulador 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;
}

O SimpleHapticsController recuperado no exemplo anterior é usado em exemplos subsequentes para consultar recursos hápticos e para enviar/parar comentários hápticos.

Observação

Se você estiver criando aplicativos com o Windows App SDK Preview 1.0, poderá usar a interoperabilidade PenDevice (PenDeviceInterop.FromPointerPoint(PointerPoint)) para acessar o sistema PenDevice.

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

As seções a seguir descrevem os recursos de feedback que as canetas hápticas devem dar suporte, bem como aqueles que são opcionais. Um tipo de feedback háptico necessário normalmente pode ser usado como um fallback em vez de um recurso opcional.

Formas de onda de escrita à tinta

As ondas de tinta são reproduzidas continuamente enquanto a caneta está em contato com a tela e tentam simular a sensação tátil de várias ferramentas de escrita ou desenho.

Característica Description Obrigatório/opcional
Forma de onda InkContinous Simula a sensação de uso de uma caneta esferográfica. Esta é a fallback padrão quando uma forma de onda de tintagem não é suportada por uma caneta háptica. Obrigatório
Forma de onda contínua do pincel Sinal háptico contínuo quando o usuário seleciona pincel como ferramenta de escrita à tinta. Opcional
Forma de onda ChiselMarkerContinuous Sinal háptico contínuo quando o usuário seleciona marcador de cinzel/realçador como ferramenta de marcação. Opcional
Forma de onda contínua Eraser Sinal háptico contínuo quando o usuário seleciona a borracha como ferramenta de desenho. Opcional
Forma de onda GalaxyContinuous
(o Guia de Documentação e Implementação HID refere-se a essa forma de onda como SparkleContinuous)
Sinal háptico contínuo para ferramentas especiais de tinta, como um pincel multicolorido. Opcional
Forma de onda Contínuo do Marcador Sinal háptico contínuo quando o usuário seleciona o marcador como ferramenta de escrita à tinta. Opcional
Onda de forma contínua PencilContinuous Sinal háptico contínuo quando o usuário seleciona lápis como ferramenta de escrita à tinta. Opcional

Formas de onda de interação

As formas de onda de interação normalmente são curtas (exceções observadas na tabela a seguir), formas de onda de feedback direto geradas sob demanda para confirmar ações-chave, como passar o mouse ou clicar em um botão, responder à conclusão de uma ação ou atrair a atenção do usuário.

Característica Description Obrigatório/opcional
Clique em forma de onda Um breve feedback sonoro de clique. Esse é o fallback padrão quando uma forma de onda de interação selecionada pelo aplicativo não é suportada por uma caneta háptica. Obrigatório
Forma de onda de erro Um sinal forte para alertar o usuário de que uma ação falhou ou ocorreu um erro. Opcional
Forma de onda de sobrevoo Indica que o usuário começou a passar o mouse sobre um elemento de interface do usuário interativo. Opcional
Selecionar forma de onda Indica quando um usuário pressiona um elemento de interface do usuário interativo em uma ação incremental (consulte Versão). Opcional
Forma de onda de liberação Indica quando um usuário libera um elemento de interface do usuário interativo em uma ação incremental (veja Press). Opcional
Forma de onda de sucesso Sinal forte para alertar o usuário de que uma ação foi bem-sucedida. Opcional
Forma de onda contínua de Buzz Sensação contínua de zumbido. Opcional
Forma de onda RumbleContinuous Sensação contínua de estrondo. Opcional

Personalizações de comentários hápticos

Algumas canetas hápticas podem dar suporte às personalizações a seguir.

Característica Description Obrigatório/opcional
Intensidade Define a intensidade do sinal háptico. Opcional
Contagem de Reprodução Repete um sinal háptico um número especificado de vezes. Opcional
Intervalo de pausa de reprodução Define o tempo entre cada reprodução repetida do sinal háptico. Opcional
Duração do jogo Define o intervalo de tempo em que um sinal háptico é reproduzido. Opcional

Verificar se há suporte a configurações personalizadas

Para verificar se há suporte para Intensidade, Contagem de Reprodução, Intervalo de Pausa de Reprodução e Duração da Reprodução, use as seguintes propriedades do SimpleHapticsController:

Enviar e interromper o feedback háptico durante a escrita à tinta

Use o método SendHapticFeedback do objeto SimpleHapticsController para passar formas de onda de escrita à tinta para a caneta do usuário. Esse método dá suporte à passagem de uma forma de onda ou a uma forma de onda com um valor de intensidade personalizado (consulte Personalizar comentários hápticos).

Chame SendHapticFeedback e passe uma forma de onda de tinta para configurar a caneta a começar a reproduzir essa forma de onda assim que a ponta da caneta tocar em algum ponto da tela. A forma de onda continuará sendo reproduzida até que a caneta seja levantada ou o StopFeedback seja chamado, o que acontecer primeiro. Recomendamos fazer isso no manipulador de eventos PointerEntered para o elemento no qual você deseja que o feedback tátil seja reproduzido. Por exemplo, um aplicativo com uma implementação de escrita à tinta personalizada faria isso no método PointerEntered de sua tela de escrita à tinta.

Para recuperar a forma de onda de escrita à tinta desejada, você deve iterar por meio da coleção SupportedFeedback do SimpleHapticsController, garantindo que ela seja compatível com a caneta ativa.

Se não houver suporte, você pode optar por não reproduzir nada ou voltar para a forma de onda InkContinuous , pois isso tem suporte garantido.

No exemplo a seguir, tentamos enviar a forma de onda BrushContinuous (mas volte para InkContinuous se BrushContinuous não tiver suporte).

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

É importante que você também pare os comentários hápticos quando o ponteiro associado sair do elemento que você registrou para comentários hápticos. Caso contrário, a forma de onda continuará tentando ser reproduzida na caneta ativa.

Observação

Algumas canetas podem, opcionalmente, parar os recursos táteis automaticamente quando a caneta sai do alcance da tela. No entanto, não é necessário que todas as canetas façam isso, portanto, os aplicativos devem sempre parar explicitamente os comentários hápticos, conforme descrito aqui.

Para interromper o feedback háptico em um elemento, registre o evento PointerExited no mesmo elemento em que você registrou o manipulador PointerEntered que enviou o sinal háptico. Nesse manipulador de eventos encerrado, chame StopFeedback , conforme mostrado aqui.

hapticsController.StopFeedback();

Enviar e parar comentários de interação

Enviar comentários de interação é bastante semelhante ao envio de comentários de escrita à tinta.

Use o método SendHapticFeedback do objeto SimpleHapticsController para passar formas de onda de interação para a caneta do usuário. Esse método dá suporte à passagem de uma forma de onda ou a uma forma de onda com um valor de intensidade personalizado (consulte Personalizar comentários hápticos).

Chame SendHapticFeedback e passe uma forma de onda de escrita à tinta para configurar a caneta para começar a reproduzir essa forma de onda imediatamente com base em alguma interação em seu aplicativo (em vez de quando a ponta da caneta toca a tela para comentários de escrita à tinta).

Ao usar qualquer uma das formas de onda de Interação não contínuas, não é necessário fazer uma chamada stopFeedback correspondente. Você ainda precisa chamar StopFeedback para as formas de onda de interação contínuas.

Observação

Enviar uma onda de interação enquanto uma onda de escrita à tinta está sendo reproduzida interromperá temporariamente a onda de escrita à tinta. A forma de onda de escrita à tinta será retomada quando o formato de onda de interação for interrompido.

Para recuperar a forma de onda de interação desejada, você deve iterar por meio da coleção SupportedFeedback do SimpleHapticsController, garantindo que ela seja compatível com a caneta ativa.

Se não houver suporte, você pode optar por não reproduzir nada ou voltar para a forma de onda Click, pois é garantido que há suporte para ela.

No exemplo a seguir, tentamos enviar a forma de onda Erro (mas recorremos ao Click se Erro não for suportado).

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

Personalizar comentários hápticos

Há três maneiras de personalizar comentários hápticos. O primeiro é compatível com feedback de Inking e de Interação, enquanto o segundo e o terceiro só têm suporte por feedback de Interação.

  1. Regule a intensidade do feedback em relação à configuração de intensidade máxima do sistema. Para fazer isso, primeiro você deve verificar se o SimpleHapticsController dá suporte à configuração da intensidade e, em seguida, chamar SendHapticFeedback com o valor desejado 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 o sinal háptico um número especificado de vezes. Para fazer isso, primeiro você deve verificar se o SimpleHapticsController dá suporte à definição da intensidade e, em seguida, chamar SendHapticFeedbackForPlayCount com o valor de contagem desejado. Você também pode definir a intensidade e o intervalo de pausa de reprodução.

    Observação

    Se o SimpleHapticsController não der suporte à definição da intensidade ou ao intervalo de pausa de reprodução, os valores fornecidos serão ignorados.

    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. Defina a duração do sinal háptico. Para fazer isso, primeiro verifique se o SimpleHapticsController dá suporte à definição da duração do jogo e, em seguida, chame SendHapticFeedbackForDuration com o valor de intervalo de tempo desejado. Você também pode definir a intensidade.

    Observação

    Se o SimpleHapticsController não der suporte à configuração da intensidade, o valor fornecido será ignorado.

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

Exemplos

Consulte o exemplo de caneta háptica para ver exemplos práticos da seguinte funcionalidade: