ペンのハプティック(触覚)フィードバック

ペン デバイスからの触覚フィードバックを使用して、Windows アプリ SDK アプリでより自然で触覚的な相互作用を提供する方法について説明します。

Windows 11デジタル ペンの触覚フィードバックが導入され、ユーザーはペンがアプリの UI と対話しているのを感じることができます。 この機能を参照する場合、触覚は開発者 API とドキュメントで使用され、触覚は Windows 設定に表示されるユーザー向けの名前です。

主要API

触覚フィードバックの種類

次の 2 種類の触覚フィードバックを利用できます。

  • 手描き入力フィードバック - ペンが画面に触れる間の連続振動によって、書き込みまたは描画ツール (ペン、マーカー、鉛筆、蛍光ペン) の感覚をシミュレートします。
  • 相互作用フィードバック - ボタンの上にマウスポインターを置いたり、クリックしたり、完了したアクションを確認したりするなどのユーザーアクションの短い触覚信号。

ペン入力を検出する

PointerEntered イベントに登録し、ポインター デバイスの種類がペンであるかどうかを確認します。

private void InputObserver_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    if (e.Pointer.PointerDeviceType != Microsoft.UI.Input.PointerDeviceType.Pen)
    {
        return;
    }

    // Pen detected — check for haptic support.
}

Windows アプリ SDKで PenDevice を取得する

Windows アプリ SDK アプリでは、PenDeviceInterop (Windows アプリ SDK相互運用クラス) を使用して、ポインター ポイントから WinRT PenDevice オブジェクトを取得します。 PenDeviceSimpleHapticsController、およびKnownSimpleHapticsControllerWaveformsは、Windows.Devices.Input名前空間とWindows.Devices.Haptics名前空間からの WinRT 型です。相互運用呼び出し自体は、Windows アプリ SDKのMicrosoft.UI.Input.Interop名前空間から取得されます。

using Microsoft.UI.Input.Interop;
using Windows.Devices.Haptics;
using Windows.Devices.Input;
using Windows.Foundation.Metadata;

private void InputObserver_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    if (e.Pointer.PointerDeviceType != Microsoft.UI.Input.PointerDeviceType.Pen)
    {
        return;
    }

    var penDevice = PenDeviceInterop.FromPointerPoint(e.GetCurrentPoint(null));

    if (penDevice == null)
    {
        return; // Pen does not support advanced features.
    }

    // SimpleHapticsController requires Windows 11. Check for API presence
    // before accessing it so the app doesn't throw on Windows 10.
    if (!ApiInformation.IsPropertyPresent(
        "Windows.Devices.Input.PenDevice", "SimpleHapticsController"))
    {
        return; // Haptic feedback requires Windows 11.
    }

    var hapticsController = penDevice.SimpleHapticsController;
    if (hapticsController == null)
    {
        return; // Pen does not support haptic feedback.
    }

    // Configure haptic feedback (see examples below).
}

UWP アプリでは、代わりに PenDevice.GetFromPointerId を使用します。 PenDeviceInterop クラスは、Windows アプリ SDKに固有です。

インク波形

ペンが画面に接触している間、インク波形が連続して再生されます。 必要な波形は、どの触覚ペンでもサポートされることが保証されています。

波形 Description 必須
InkContinuous 既定のボールポイント ペンフィール。 サポートされていない波形のフォールバック。 はい
BrushContinuous (ブラシ・コンティニュアス) ブラシツール いいえ
ペンシル連続 鉛筆ツール いいえ
MarkerContinuous マーカーツール いいえ
ChiselMarkerContinuous チゼルマーカー/蛍光ペン いいえ
連続消しゴム 消しゴムツール いいえ
GalaxyPenContinuous 特殊インク(多色ブラシ) いいえ

相互作用波形

相互作用波形は、UI アクションに対して短く直接的なフィードバックを提供します。

波形 Description 必須
Click 既定の短いクリック。 サポートされていない操作に対する代替処理。 はい
エラー アクションが失敗したか、エラーが発生しました いいえ
Hover 対話型要素の上にマウス ポインターを置き始めた いいえ
押す インタラクティブ要素をクリックした いいえ
Release 対話型要素を解放しました いいえ
成功 アクションが成功しました いいえ
BuzzContinuous 連続ブザー音 いいえ
RumbleContinuous 連続振動 いいえ

触覚フィードバックを送信する

SupportedFeedbackを反復処理して目的の波形を見つけ、SendHapticFeedbackを呼び出します。

SimpleHapticsControllerFeedback currentWaveform = null;

// Try to use BrushContinuous, fall back to InkContinuous.
foreach (var waveform in hapticsController.SupportedFeedback)
{
    if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.BrushContinuous)
    {
        currentWaveform = waveform;
        break;
    }
}

if (currentWaveform == null)
{
    foreach (var waveform in hapticsController.SupportedFeedback)
    {
        if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.InkContinuous)
        {
            currentWaveform = waveform;
            break;
        }
    }
}

if (currentWaveform != null)
{
    hapticsController.SendHapticFeedback(currentWaveform);
}

触覚フィードバックを停止する

ポインターが要素を終了したときに、触覚フィードバックを常に停止します。 同じ要素で PointerExited を登録します:

private void Canvas_PointerExited(object sender, PointerRoutedEventArgs e)
{
    hapticsController?.StopFeedback();
}

一部のペンは、ペンが画面を離れると自動的に触覚を停止します。 ただし、すべてのペンでこれを行うわけではないため、常に明示的に StopFeedback 呼び出します。

触覚フィードバックをカスタマイズする

一部のペンでは、追加のカスタマイズがサポートされています。 使用する前にサポートを確認してください。

プロパティ サポートを確認する
強度 IsIntensitySupported
再生回数 IsPlayCountSupported
再生時間 IsPlayDurationSupported
再生の一時停止間隔 IsReplayPauseIntervalSupported
if (hapticsController.IsIntensitySupported)
{
    hapticsController.SendHapticFeedback(currentWaveform, 0.75); // 75% intensity
}