Interazioni con penna e feedback aptico (tattile)

Da molto tempo Windows supporta tempo penne digitali che consentono agli utenti di interagire con i propri dispositivi in modo naturale e diretto e di esprimere la propria creatività attraverso esperienze di scrittura e disegno ricche usando l'input penna digitale.

Con Windows 11, viene introdotta una nuova funzionalità che rende l'esperienza della penna digitale ancora più naturale e accattivante: quando si usa una penna che supporta il "feedback aptico", gli utenti possono effettivamente sentire la penna interagire in modo tattile con l'interfaccia utente di un'app.

Nota

Quando si fa riferimento a questa nuova funzionalità, il termine "aptico" viene usato in tutte le API per sviluppatori e nella documentazione correlata, mentre "tattile" è il nome descrittivo presentato agli utenti per impostare le preferenze di feedback nelle Impostazioni di Windows.

Le esperienze di feedback aptico supportate in Windows 11 includono feedback di input penna e feedback di interazione:

  • Il feedback input penna simula la sensazione di vari tipi di strumenti di scrittura o disegno (ad esempio penna, pennarello, matita, evidenziatore e così via) attraverso vibrazioni continue mentre la penna è in contatto con lo schermo. Per impostazione predefinita, la piattaforma Windows Ink supporta il feedback aptico per tutti gli strumenti di disegno (questa sezione illustra come fornire una soluzione di input penna personalizzata oltre a quella supportata da Windows Ink).
  • Il feedback di interazione, d'altra parte, è un feedback diretto basato su azioni chiave dell'utente, ad esempio il passaggio del mouse sopra un pulsante o il clic su di esso, la risposta al completamento di un'azione o il richiamo della sua attenzione.

In genere, sono necessari cinque passaggi per supportare completamente il feedback aptico:

  • Rilevare l'input penna.
  • Determinare se la penna corrente e il dispositivo supportano il feedback aptico e, in tal caso, quali funzionalità di feedback aptico supportano.
  • Decidere il segnale di feedback aptico da inviare.
  • Inviare il feedback aptico.
  • Arrestare il feedback aptico

Rilevare l'input penna

Per rilevare e isolare l'input penna, è prima necessario registrarsi all'evento PointerEntered e quindi controllare se PointerDeviceType è una penna.

Il codice seguente illustra come controllare il tipo di dispositivo puntatore all'interno di un evento PointerEntered. In questo esempio, se l'input non proviene da una penna, viene semplicemente restituito dal gestore eventi. In caso contrario, si controllano le funzionalità della penna e si configura il feedback aptico.


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

Determinare il supporto per il feedback aptico

Non tutte le penne e i digitalizzatori supportano il feedback aptico e le penne che lo fanno non supportano necessariamente tutte le funzionalità di feedback aptico descritte in questa sezione. Di conseguenza, è importante verificare a livello di codice quali funzionalità sono supportate dalla penna attiva.

In una continuazione dell'esempio precedente viene illustrato come verificare se la penna attiva supporta il feedback aptico.

Per prima cosa si tenta di recuperare un oggetto PenDevice dall'elemento PointerId corrente. Se non è possibile ottenere un oggetto PenDevice, il gestore eventi semplicemente si conclude.

Se è stato ottenuto un oggetto PenDevice , viene verificato se supporta una proprietà SimpleHapticsController. In caso contrario, il gestore eventi di nuovo semplicemente si conclude.

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

L'oggetto SimpleHapticsController recuperato nell'esempio precedente viene usato negli esempi successivi per eseguire query sulle funzionalità aptiche e per inviare/arrestare il feedback aptico.

Nota

Se si creano app con l'SDK per app di Windows Preview 1.0 è possibile usare l'interoperabilità PenDevice (PenDeviceInterop.FromPoint(PointerPoint)) per accedere al sistema PenDevice.

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

Le sezioni seguenti descrivono le funzionalità di feedback che le penne con funzionalità aptiche devono supportare, nonché quelle facoltative. Un tipo di feedback aptico necessario può in genere essere usato come fallback anziché come funzionalità facoltativa.

Forme d'onda input penna

Le forme d'onda input penna vengono riprodotte continuamente quando la penna è in contatto con lo schermo e tentano di simulare l'impressione di diversi strumenti di scrittura o disegno.

Funzionalità Descrizione Obbligatoria / Facoltativa
Forma d'onda InkContinous Simula la sensazione dell'utilizzo di input penna con una penna a sfera fisica. Si tratta del fallback predefinito quando una forma d'onda input penna non è supportata da una specifica penna con funzionalità aptiche. Richiesto
Forma d'onda BrushContinuous Segnale aptico continuo usato quando l'utente seleziona pennello come strumento di input penna. Facoltativo
Forma d'onda ChiselMarkerContinuous Segnale aptico continuo usato quando l'utente seleziona pennarello/evidenziatore come strumento di input penna. Facoltativo
Forma d'onda eraserContinuous Segnale aptico continuo usato quando l'utente seleziona gomma per cancellare come strumento di input penna. Facoltativo
Forma d'onda GalaxyContinuous
(la documentazione e la guida all'implementazione diHID fa riferimento a questa forma d'onda come SparkleContinuous)
Segnale aptico continuo per strumenti speciali, ad esempio un pennello multicolore. Facoltativo
Forma d'onda MarkerContinuous Segnale aptico continuo usato quando l'utente seleziona pennarello come strumento di input penna. Facoltativo
Forma d'onda PencilContinuous Segnale aptico continuo usato quando l'utente seleziona matita come strumento di input penna. Facoltativo

Forme d'onda di interazione

Le forme d'onda di interazione sono in genere forme d'onda di feedback brevi (con le eccezioni indicate nella tabella seguente) e dirette generate su richiesta per confermare azioni chiave, ad esempio il passaggio del mouse sopra un pulsante o il clic su di esso, la risposta al completamento di un'azione o il richiamo dell'attenzione dell'utente.

Funzionalità Descrizione Obbligatoria / Facoltativa
Forma d'onda Click Un breve feedback per un "clic". Si tratta del fallback predefinito quando una forma d'onda di interazione selezionata dall'app non è supportata da una penna aptica. Richiesto
Forma d'onda Error Un segnale intenso per avvisare l'utente che un'azione non è riuscita o si è verificato un errore. Facoltativo
Forma d'onda Hover Indica che l'utente ha iniziato a passare il puntatore del mouse su un elemento interattivo dell'interfaccia utente. Facoltativo
Forma d'onda Press Indica quando un utente preme un elemento interattivo dell'interfaccia utente in un'azione incrementale (vedere Rilascio). Facoltativo
Forma d'onda Release Indica quando un utente rilascia un elemento interattivo dell'interfaccia utente in un'azione incrementale (vedere Pressione). Facoltativo
Forma d'onda Success Segnale intenso per avvisare l'utente che un'azione si è conclusa correttamente. Facoltativo
Forma d'onda BuzzContinuous Sensazione di ronzio continuo. Facoltativo
Forma d'onda RumbleContinuous Sensazione di rombo continuo. Facoltativo

Personalizzazioni del feedback aptico

Alcune penne con supporto delle funzionalità aptiche possono supportare le seguenti personalizzazioni.

Funzionalità Descrizione Obbligatoria / Facoltativa
Intensità Imposta l'intensità del segnale aptico. Facoltativo
Numero di riproduzioni Ripete un segnale aptico un numero specificato di volte. Facoltativo
Intervallo pausa riproduzione Imposta il tempo tra ogni riproduzione ripetuta del segnale aptico. Facoltativo
Durata riproduzione Imposta l'intervallo di tempo durante il quale viene riprodotto un segnale aptico. Facoltativo

Verificare il supporto delle impostazioni personalizzate

Per verificare il supporto di intensità, numero di riproduzioni, intervallo pausa riproduzione e durata riproduzione, usare le proprietà seguenti di SimpleHapticsController:

Inviare e interrompere il feedback aptico dell'input penna

Utilizzare il metodo SendHapticFeedback dell'oggetto SimpleHapticsController per passare forme d'onda di input penna alla penna dell'utente. Questo metodo supporta il passaggio di una forma d'onda o di entrambe le forme d'onda con un valore di intensità personalizzato (vedere Personalizzare il feedback aptico).

Chiamare SendHapticFeedback e passare una forma d'onda input penna per configurare la penna affinché possa iniziare a riprodurre tale forma d'onda non appena la punta della penna tocca un qualsiasi punto dello schermo. La forma d'onda continuerà a essere riprodotta finché la penna non viene sollevata o viene invocato il metodo StopFeedback, qualsiasi condizione si verifichi per prima. È consigliabile eseguire questa operazione nel gestore eventi PointerEntered per l'elemento in cui si desidera riprodurre gli effetti aptici. Ad esempio, un'app con un'implementazione di input penna personalizzato eseguirà questa operazione nel metodo PointerEntered del relativo canvas di input penna.

Per recuperare la forma d'onda di input penna desiderata, è necessario scorrere la raccolta SupportedFeedback di SimpleHapticsController, assicurandosi che sia supportata dalla penna attiva.

Se non è supportata, è possibile scegliere di non riprodurre nulla o eseguire il fallback alla forma d'onda InkContinuous, perché il supporto di quest'ultima è garantito.

Nell'esempio seguente si tenta di inviare la forma d'onda BrushContinuous (ma si esegue il fallback a InkContinuous se BrushContinuous non è supportata).

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 anche arrestare il feedback aptico quando il puntatore associato esce dall'elemento registrato per il feedback aptico. In caso contrario, la forma d'onda continuerà a essere riprodotta sulla penna attiva.

Nota

Alcune penne possono facoltativamente arrestare gli effetti aptici autonomamente quando la penna lascia la superficie dello schermo. Tuttavia, non è obbligatorio per le penne eseguire tale operazione, quindi le applicazioni devono sempre interrompere in modo esplicito il feedback aptico come descritto qui.

Per interrompere il feedback aptico su un elemento, registrarsi all'evento PointerExited sullo stesso elemento registrato dal gestore PointerEntered che ha inviato il segnale aptico. In tale gestore degli eventi di uscita chiamare StopFeedback come illustrato di seguito.

hapticsController.StopFeedback();

Inviare e interrompere il feedback di interazione

L'invio del feedback di interazione è molto simile all'invio di feedback per l'input penna.

Utilizzare il metodo SendHapticFeedback dell'oggetto SimpleHapticsController per passare forme d'onda di interazione penna alla penna dell'utente. Questo metodo supporta il passaggio di una forma d'onda o di entrambe le forme d'onda con un valore di intensità personalizzato (vedere Personalizzare il feedback aptico).

Chiamare SendHapticFeedback e passare una forma d'onda input penna per configurare la penna affinché inizi a riprodurre immediatamente tale forma d'onda in base a un'interazione all'interno dell'app (anziché quando la punta della penna tocca lo schermo per il feedback input penna).

Quando si usa una delle forme d'onda di interazione non continue, non è necessario effettuare una chiamata StopFeedback corrispondente. È comunque necessario chiamare StopFeedback per le forme d'onda di interazione continue.

Nota

L'invio di una forma d'onda di interazione quando viene riprodotta una forma d'onda di input penna interromperà temporaneamente la forma d'onda input penna. La forma d'onda dell'input penna riprenderà quando si arresta la forma d'onda di interazione.

Per recuperare la forma d'onda di interazione desiderata, è necessario scorrere la raccolta SupportedFeedback di SimpleHapticsController, assicurandosi che sia supportata dalla penna attiva.

Se non è supportata, è possibile scegliere di non riprodurre nulla o eseguire il fallback alla forma d'onda Click, perché il supporto di quest'ultima è garantito.

Nell'esempio seguente si tenta di inviare la forma d'onda Error (ma si esegue il fallback a Click se Error non è supportata).

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

Personalizzare il feedback aptico

Esistono tre modi per personalizzare il feedback aptico. Il primo è supportato sia dal feedback di input penna che da quello di interazione, mentre il secondo e il terzo sono supportati solo dal feedback di interazione.

  1. Regolare l'intensità del feedback rispetto all'impostazione massima dell'intensità del sistema. A tale scopo, è prima necessario verificare che SimpleHapticsController supporti l'impostazione dell'intensità e quindi chiamare SendHapticFeedback con il valore Intensity desiderato.

    if (hapticsController.IsIntensitySupported) 
    {
        foreach (var waveform in hapticsController.SupportedFeedback)
        {
            if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Click)
            {
                double intensity = 0.75;
                hapticsController.SendHapticFeedback(waveform, intensity);
            }
        }
    }
    
  2. Ripetere un segnale aptico un numero specificato di volte. A tale scopo, è prima necessario verificare che SimpleHapticsController supporti l'impostazione dell'intensità e quindi chiamare SendHapticFeedbackForPlayCount con il valore numerico desiderato. È anche possibile impostare sia l'intensità che l'intervallo di pausa di riproduzione.

    Nota

    Se SimpleHapticsController non supporta l'impostazione dell'intensità o l'intervallo di pausa di riproduzione, i valori specificati verranno ignorati.

    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. Impostare la durata del segnale aptico. A tale scopo, è prima necessario verificare che SimpleHapticsController supporti l'impostazione della durata di riproduzione e quindi chiamare SendHapticFeedbackForDuration con il valore dell'intervallo di tempo desiderato. È anche possibile impostare l'intensità.

    Nota

    Se SimpleHapticsController non supporta l'impostazione dell'intensità, il valore fornito verrà ignorato.

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

Esempi

Per esempi funzionanti delle funzionalità seguenti, vedere l'esempio di penna aptica: