Menerapkan umpan balik haptik di aplikasi Windows

Artikel ini menjelaskan cara menambahkan umpan balik haptik ke aplikasi Windows Anda menggunakan API InputHapticsManager, termasuk contoh kode untuk pola interaksi umum.

Untuk panduan desain tentang kapan dan mengapa menggunakan haptik, lihat Panduan desain Haptics.

Perangkat yang didukung

Umpan balik haptik didukung oleh perangkat input seperti mouse, touchpad, dan pena digital. Ketersediaan bervariasi menurut model dan produsen. Selalu periksa dukungan saat runtime sebelum memanggil API haptics (lihat Periksa dukungan di bawah).

Requirements

Persyaratan Rincian
Namespace Windows.Devices.Haptics
Minimum OS Windows 11, SDK 10.0.28000.1721 (Maret 2026)
Ratakan / Bertabrakan / Langkah / Tumbuhkan bentuk gelombang SDK 10.0.28000.1839 (April 2026)
Kontrak API UniversalApiContract versi 19.0

Untuk menargetkan versi OS sebelumnya, gunakan ApiInformation.IsTypePresent untuk menjaga semua panggilan (lihat kode di bawah).

Periksa dukungan

Selalu verifikasi bahwa API tersedia dan ada perangkat haptic sebelum digunakan. API tidak ada pada versi OS yang lebih lama, dan tidak semua perangkat input mendukung haptics.

using Windows.Devices.Haptics;
using Windows.Foundation.Metadata;

// Guard against older OS versions where the API is absent.
bool apiPresent = ApiInformation.IsTypePresent("Windows.Devices.Haptics.InputHapticsManager");

// Check that a supported haptic device is connected.
bool supported = apiPresent && InputHapticsManager.IsSupported();

Memicu bentuk gelombang

Panggil InputHapticsManager.GetForCurrentThread() di utas UI untuk mendapatkan instance pengelola yang berlaku untuk fokus input utas saat ini. Deteksi dan perutean perangkat ditangani secara otomatis—Anda tidak perlu menghitung perangkat sendiri.

using Windows.Devices.Haptics;

if (supported)
{
    var mgr = InputHapticsManager.GetForCurrentThread();

    // The second parameter is a fallback waveform used if the first is
    // unsupported. Passing 0 lets the system choose a device-appropriate
    // fallback. TrySendHapticWaveform returns false if neither waveform is
    // supported; this is a non-fatal condition.
    bool sent = mgr.TrySendHapticWaveform(
        KnownSimpleHapticsControllerWaveforms.Align,
        0);
}

Important

Panggil GetForCurrentThread() dari utas UI (atau utas yang memiliki fokus input). Memanggilnya dari utas latar belakang tidak akan mengarahkan umpan balik ke perangkat yang tepat.

Hentikan pemutaran

Panggil TryStopFeedback saat penyeretan atau interaksi berakhir untuk menghentikan pemutaran haptik yang sedang berlangsung.

using Windows.Devices.Haptics;

if (supported)
{
    InputHapticsManager
        .GetForCurrentThread()
        .TryStopFeedback();
}

Contoh implementasi

Perataan objek

Panduan penyelarasan umum digunakan di alat desain, editor presentasi, dan aplikasi pembuatan diagram. Umpan balik haptik menambahkan saluran kedua sehingga pengguna dapat merasakan saat objek terkunci pada tempatnya—mengurangi kebutuhan untuk memperbesar tampilan guna mengonfirmasi keselarasan secara visual.

Kapan harus menembak: Gunakan tampilan panduan perataan sebagai pemicu. Ketika logika snap Anda menunjukkan panduan, aktifkan haptic. Jika tidak ada panduan yang muncul, jangan tembak. Ini membuat peristiwa haptik tetap erat digabungkan dengan umpan balik sistem yang terlihat.

Hindari duplikat: Bentuk dapat selaras dengan beberapa panduan secara bersamaan (misalnya, tepi kiri dan tepi atas). Perlakukan ini sebagai interaksi tunggal—lacak panduan aktif dan hanya aktifkan saat panduan baru muncul.

using Windows.Devices.Haptics;

private readonly HashSet<int> _activeGuides = new();

// Call this after computing which alignment guides are currently visible.
void OnGuidesUpdated(IEnumerable<int> currentGuideIds)
{
    var currentGuides = currentGuideIds.ToHashSet();

    bool hasNewGuide = currentGuides.Except(_activeGuides).Any();

    // Update the tracked set in place (field is readonly).
    _activeGuides.Clear();
    _activeGuides.UnionWith(currentGuides);

    if (hasNewGuide && supported)
    {
        InputHapticsManager.GetForCurrentThread()
            .TrySendHapticWaveform(
                KnownSimpleHapticsControllerWaveforms.Align,
                0);
    }
}

Sliders

Umpan balik haptik meningkatkan interaksi penggeser dengan menautkan umpan balik ke posisi-posisi penting. Selalu ikat umpan balik ke penanda yang terlihat yang dapat dipahami pengguna—tanda centang, nilai bernama, atau batas rentang.

Kapan harus menembak: Haptik api saat ibu jari melintasi setiap tanda centang. Hindari umpan balik berkelanjutan antara kutu, yang dapat terasa mengganggu.

using Windows.Devices.Haptics;

double _previousValue;
const double TickInterval = 25.0;

void OnSliderValueChanged(double newValue)
{
    int previousTick = (int)(_previousValue / TickInterval);
    int currentTick  = (int)(newValue       / TickInterval);

    if (currentTick != previousTick && supported)
    {
        InputHapticsManager.GetForCurrentThread()
            .TrySendHapticWaveform(
                KnownSimpleHapticsControllerWaveforms.Step,
                0);
    }

    _previousValue = newValue;
}

Menyempurnakan pengalaman: Skalakan intensitas haptik berdasarkan posisi pengguncur untuk membantu pengguna merasakan di mana mereka berada dalam rentang. Gunakan TrySendHapticWaveformForPlayCount, yang menerima nilai intensitas eksplisit dari 0.0 ke 1.0.

void OnSliderValueChangedWithIntensity(double newValue, double maxValue)
{
    int previousTick = (int)(_previousValue / TickInterval);
    int currentTick  = (int)(newValue       / TickInterval);

    if (currentTick != previousTick && supported)
    {
        double intensity = newValue / maxValue; // Scale 0.0–1.0

        InputHapticsManager.GetForCurrentThread()
            .TrySendHapticWaveformForPlayCount(
                KnownSimpleHapticsControllerWaveforms.Step,
                0,          // fallback waveform
                intensity,
                1,          // playCount
                TimeSpan.Zero);
    }

    _previousValue = newValue;
}

Seret interaksi dan deteksi niat

Saat menyeret, sebuah objek dapat melintasi banyak batas penyelarasan—pusat halaman, garis panduan, dan objek lainnya. Memberikan umpan balik haptik setiap kali melewati titik persilangan dapat membuat pengguna kewalahan, terutama saat bergerak cepat ketika mereka sedang mengubah posisi, bukan berusaha bergerak dengan presisi.

Gunakan pendeteksian niat untuk memicu umpan balik hanya saat pengguna berusaha menyelaraskan secara sengaja, bukan sekadar melintas.

Pendekatan 1: Filter kecepatan

Nonaktifkan umpan balik haptik saat kursor bergerak cepat, agar umpan balik hanya diberikan untuk gerakan yang lebih lambat dan lebih disengaja.

  • Stabilkan sinyalnya. Hindari menggunakan delta kursor mentah, yang dapat berisik di seluruh jenis input, pengaturan DPI, dan konfigurasi tampilan. Menormalkan dan menghaluskan sinyal.
  • Pilih ambang batas dengan hati-hati. Lakukan validasi pada berbagai perangkat, jenis masukan, skala tampilan, dan konfigurasi multi-layar.

Pendekatan 2: Debounce dengan timer

Saat objek memasuki zona pemicu, mulai timer singkat (50 ms adalah titik awal yang wajar). Jika objek tetap berada di zona saat pengatur waktu berakhir, anggap itu sebagai tindakan yang disengaja dan picu umpan balik haptik. Jika objek bergerak sebelum timer berbunyi, jangan tampilkan umpan balik.

  • Lebih mudah diimplementasikan dan cenderung menghasilkan perilaku yang lebih stabil daripada pemfilteran kecepatan.
  • Penundaan 50 ms cukup lama untuk membedakan keselarasan yang disarankan dari pass cepat, sementara tetap di bawah ambang latensi yang terlihat.
using System;
using Microsoft.UI.Xaml;
using Windows.Devices.Haptics;

private DispatcherTimer? _alignTimer;

void OnObjectEnteredAlignmentZone()
{
    _alignTimer?.Stop();
    _alignTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(50) };
    _alignTimer.Tick += (_, _) =>
    {
        _alignTimer.Stop();
        if (supported)
        {
            InputHapticsManager.GetForCurrentThread()
                .TrySendHapticWaveform(
                    KnownSimpleHapticsControllerWaveforms.Align,
                    0);
        }
    };
    _alignTimer.Start();
}

void OnObjectLeftAlignmentZone()
{
    _alignTimer?.Stop();
}

Memilih di antara keduanya

Filter berdasarkan kecepatan Pewaktu debounce
Cara kerjanya Reaktif—mengukur pergerakan secara waktu nyata Prediktif—menunggu sebentar untuk mengonfirmasi niat
Merasa Terasa lebih instan Sedikit tertunda, tetapi lebih konsisten
Upaya penyetelan Lebih tinggi—membutuhkan kalibrasi yang cermat Lebih rendah—nilai penundaan tunggal biasanya cukup
Disarankan untuk Aplikasi yang membutuhkan umpan balik yang sangat responsif Sebagian besar aplikasi; titik awal default yang baik