Windows는 사용자가 자연스럽고 직접적인 방식으로 디바이스와 상호 작용하고 디지털 잉크를 사용하여 풍부한 쓰기 및 그리기 환경을 통해 창의력을 표현할 수 있도록 하는 디지털 펜을 오랫동안 지원해 왔습니다.
Windows 11에서는 디지털 펜 환경을 더욱 자연스럽고 매력적으로 만드는 새로운 기능이 도입되고 있습니다. "촉각 피드백"을 지원하는 펜을 사용하는 경우 사용자는 실제로 앱의 UI(사용자 인터페이스)와 촉각 방식으로 상호 작용하는 펜을 느낄 수 있습니다.
비고
이 새로운 기능을 지칭할 때, 개발자 API 및 관련 문서에서는 "햅틱"을 사용하는 반면, Windows 설정에서는 사용자들에게 피드백 기본 설정을 위해 "촉각"이라는 친숙한 용어가 제공됩니다.
Windows 11에서 지원되는 촉각 피드백 경험에는 수동 입력 피드백 및 상호 작용 피드백이 포함됩니다.
- 필기 피드백은 펜이 화면과 접촉하는 동안 연속적인 진동을 통해 펜, 마커, 연필, 형광펜 등 다양한 쓰기 또는 그리기 도구의 느낌을 시뮬레이션합니다. 기본적으로 Windows Ink Platform 은 모든 그리기 도구에 대한 촉각 피드백을 지원합니다(이 항목에서는 Windows Ink에서 지원하는 것 이상으로 사용자 지정 수동 입력 솔루션을 제공하는 방법에 대해 설명합니다).
- 반면 상호 작용 피드백은 단추를 마우스로 가리키거나 클릭하거나, 작업 완료에 응답하거나, 사용자의 관심을 끄는 등의 주요 사용자 작업을 기반으로 하는 직접 피드백입니다.
일반적으로 촉각 피드백을 완전히 지원하려면 5단계가 필요합니다.
- 펜 입력을 감지합니다.
- 현재 펜 및 디바이스가 촉각 피드백을 지원하는지, 그렇다면 어떤 촉각 피드백 기능을 지원하는지 확인합니다.
- 보낼 촉각 피드백 신호를 결정합니다.
- 촉각 피드백을 보냅니다.
- 촉각 피드백 중지
펜 입력 감지
펜 입력을 감지하고 격리하려면 먼저 PointerEntered 이벤트에 등록하고, 그 후에 PointerDeviceType이 펜인지 확인해야 합니다.
다음 코드에서는 PointerEntered 이벤트 내에서 포인터 디바이스 형식을 확인하는 방법을 보여 있습니다. 이 예제에서는 입력이 펜에서 온 것이 아니면 이벤트 처리기에서 반환하기만 하면됩니다. 그렇지 않으면 펜 기능을 확인하고 촉각 피드백을 구성합니다.
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;
}
...
}
촉각 피드백에 대한 지원 확인
모든 펜과 디지타이저가 촉각 피드백을 지원하는 것은 아니며, 이 항목에 설명된 모든 촉각 피드백 기능을 반드시 지원하지는 않습니다. 따라서 활성 펜에서 지원하는 기능을 프로그래밍 방식으로 확인하는 것이 중요합니다.
앞의 예제의 연속에서 활성 펜이 촉각 피드백을 지원하는지 여부를 확인하는 방법을 보여 줍니다.
먼저 현재 PointerId에서 PenDevice 개체를 검색하려고 합니다. PenDevice 가져올 수 없는 경우 이벤트 처리기에서 반환하기만 하면 됩니다.
PenDevice를 가져온 경우, SimpleHapticsController 속성을 지원하는지 테스트합니다. 그렇지 않은 경우 이벤트 처리기에서 다시 반환합니다.
// 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 는 후속 예제에서 촉각 기능을 쿼리하고 촉각 피드백을 보내거나 중지하는 데 사용됩니다.
비고
Windows 앱 SDK Preview 1.0사용하여 앱을 빌드하는 경우 PenDevice interop(PenDeviceInterop.FromPointerPoint(PointerPoint))를 사용하여 시스템 PenDevice액세스할 수 있습니다.
private void InputObserver_PointerEntered(PointerInputObserver sender, PointerEventArgs args)
{
var penDevice = PenDeviceInterop.PenDeviceFromPointerPoint(args.CurrentPoint);
}
다음 섹션에서는 촉각 펜이 지원해야 하는 피드백 기능과 선택 사항인 피드백 기능에 대해 설명합니다. 필수적인 촉각 피드백 유형은 일반적으로 선택적 기능 대신 대체 기능으로 사용할 수 있습니다.
잉크파형
잉크 파형은 펜이 화면과 접촉하는 동안 지속적으로 재생되며 다양한 쓰기 또는 그리기 도구의 느낌을 시뮬레이션하려고 시도합니다.
특징 | 설명 | 필수/선택 사항 |
---|---|---|
InkContinous 파형 | 실제 볼펜으로 잉킹하는 느낌을 시뮬레이션합니다. 잉킹 파형이 촉각 펜에서 지원되지 않을 때의 기본 대체입니다. | 필수 |
BrushContinuous 파형 | 사용자가 잉킹 도구로 브러시를 선택할 때 연속 촉각 신호가 발신됩니다. | 선택적 |
ChiselMarkerContinuous 파형 | 사용자가 잉크 도구로 끌 마커나 형광펜을 선택할 때 연속적인 촉각 신호가 전달됩니다. | 선택적 |
연속 지우개 파형 | 사용자가 잉킹 도구로 지우개를 선택할 때 지속적인 촉각 신호가 발생합니다. | 선택적 |
갤럭시 연속 파형 (HID 설명서 및 구현 가이드는 이 파형을 SparkleContinuous이라고 합니다) |
멀티 컬러 브러시와 같은 특수 잉크 도구에 대한 연속 촉각 신호입니다. | 선택적 |
마커 연속형 파형 | 사용자가 마커를 잉킹 도구로 선택할 때 연속적인 촉각 신호가 발생합니다. | 선택적 |
연속 펜슬 파형 | 사용자가 잉크 도구로 연필을 선택할 때 연속적인 촉각 신호가 전해집니다. | 선택적 |
상호 작용 파형
상호 작용 파형은 일반적으로 짧으며(다음 표에 나와 있는 예외), 단추를 가리키거나 클릭하거나, 작업 완료에 응답하거나, 사용자의 주의를 끌기 위해 단추를 가리키거나 클릭하는 등의 주요 작업을 확인하기 위해 요청 시 생성된 직접 피드백 파형입니다.
특징 | 설명 | 필수/선택 사항 |
---|---|---|
파형 클릭 | 짧은 "클릭" 피드백입니다. 앱에서 선택한 상호 작용 파형이 촉각 펜에서 지원되지 않는 경우 기본 대체입니다. | 필수 |
오류 파형 | 사용자에게 작업이 실패했거나 오류가 발생했음을 알리는 강력한 신호입니다. | 선택적 |
호버 파형 | 사용자가 대화형 UI 요소 위로 마우스를 가져가기 시작했음을 나타냅니다. | 선택적 |
파형을 누릅니다. | 사용자가 증분 작업에서 대화형 UI 요소를 누를 때를 나타냅니다(릴리스 참조). | 선택적 |
릴리스 파형 | 사용자가 점진적 작업에서 대화형 UI 요소를 놓는 경우를 나타냅니다(Press 참조). | 선택적 |
성공 파형 | 사용자에게 작업이 성공했음을 알리는 강력한 신호입니다. | 선택적 |
버즈 연속 파형 | 지속적으로 윙윙거리는 느낌. | 선택적 |
럼블연속 파형 | 연속 덜컹 거리는 감각. | 선택적 |
촉각 피드백 사용자 지정
일부 촉각 펜은 다음 사용자 지정을 지원할 수 있습니다.
특징 | 설명 | 필수/선택 사항 |
---|---|---|
강도 | 촉각 신호의 강도를 설정합니다. | 선택적 |
플레이 횟수 | 지정된 횟수만큼 촉각 신호를 반복합니다. | 선택적 |
재생 일시 중지 간격 | 촉각 신호의 반복 재생 사이의 시간을 설정합니다. | 선택적 |
재생 기간 | 촉각 신호가 재생되는 시간 간격을 설정합니다. | 선택적 |
사용자 지정 설정 지원 확인
강도, 재생 수, 재생 일시 중지 간격 및 재생 기간 지원을 확인하려면 SimpleHapticsController의 다음 속성을 사용합니다.
- 강도가 지원되는지 확인
- isPlayCountSupported
- IsPlayDurationSupported
- 재생 일시정지 간격 지원 여부
잉킹 촉각 피드백 전송 및 중지
SendHapticFeedback 메서드를 사용하여 SimpleHapticsController 개체의 사용자 펜에 잉크 파형을 전달합니다. 이 메서드는 파형 하나만 전달하거나 사용자 지정된 강도 값을 사용한 파형을 전달하는 것을 지원합니다 (촉각 피드백 사용자 지정참조).
SendHapticFeedback을 호출하고 잉크 입력 파형을 전달함으로써 펜 끝이 화면의 어느 지점에 닿으면 즉시 그 파형을 재생하도록 펜을 구성합니다. 파형은 펜이 해제되거나 StopFeedback이 호출될 때, 중 먼저 발생하는 상황까지 계속 재생됩니다. 촉각을 재생하려는 요소에 대한 PointerEntered 이벤트 처리기에서 이 작업을 수행하는 것이 좋습니다. 예를 들어 사용자 지정 수동 입력 구현을 사용하는 앱은 잉크 캔버스의 PointerEntered 메서드에서 이 작업을 수행합니다.
원하는 잉킹 파형을 검색하려면, 활성 펜에서 지원되는지 확인하면서 SupportedFeedback 컬렉션을 반복하는 SimpleHapticsController를 사용해야 합니다.
지원되지 않는 경우 아무것도 재생하지 않기를 선택하거나, 지원이 보장되는 InkContinuous 파형을 선택할 수 있습니다.
다음 예제에서는 BrushContinuous 파형을 보내려고 시도하지만 BrushContinuous 가 지원되지 않는 경우 InkContinuous로 대체합니다.
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);
연결된 포인터가 촉각 피드백을 위해 등록한 요소를 종료할 때 촉각 피드백도 중지해야 합니다. 그렇지 않으면 파형은 활성 펜에서 계속 재생을 시도합니다.
비고
일부 펜은 필요에 따라 펜이 화면 범위를 벗어나면 자체적으로 촉각을 중지할 수 있습니다. 그러나 모든 펜이 이 작업을 수행할 필요는 없으므로 애플리케이션은 여기에 설명된 대로 항상 촉각 피드백을 명시적으로 중지해야 합니다.
요소에 대한 촉각 피드백을 중지하려면, 촉각 신호를 보낸 PointerEntered 처리기를 등록했던 것과 동일한 요소에서 PointerExited 이벤트에 등록하십시오. 종료된 이벤트 처리기에서 여기에 표시된 대로 StopFeedback 을 호출합니다.
hapticsController.StopFeedback();
상호 작용 피드백 보내기 및 중지
상호 작용 피드백을 보내는 것은 잉크 피드백을 보내는 것과 매우 유사합니다.
SimpleHapticsController 개체의 SendHapticFeedback 메서드를 사용하여 상호 작용 파형을 사용자의 펜에 전달합니다. 이 메서드는 파형 하나만 전달하거나 사용자 지정된 강도 값을 사용한 파형을 전달하는 것을 지원합니다 (촉각 피드백 사용자 지정참조).
SendHapticFeedback을 호출하고 인킹 파형을 전달하여, 앱 내 상호작용이 발생했을 때 펜이 즉시 그 파형을 재생하도록 설정합니다(잉킹 피드백을 위해 펜 끝이 화면에 닿을 때 대신).
비연속 상호 작용 파형을 사용하는 경우 해당 StopFeedback 호출을 수행할 필요가 없습니다. 연속 상호 작용 파형을 위해 여전히 StopFeedback을 호출해야 합니다.
비고
잉킹 파형이 재생되는 동안 상호 작용 파형을 보내면 잉킹 파형이 일시적으로 중단됩니다. 상호 작용 파형이 중지될 때 잉크 파형이 다시 시작됩니다.
원하는 상호 작용 파형검색하려면 SimpleHapticsControllerSupportedFeedback 컬렉션을 반복하여 활성 펜에서 지원되도록 해야 합니다.
지원되지 않는 경우, 아무 것도 재생하지 않거나, 지원이 확실하게 보장되는 클릭 파형으로 대체하도록 선택할 수 있습니다.
다음 예제에서는 오류 파형을 보내려고 시도하지만, 오류가 지원되지 않는 경우 클릭으로 대체합니다.
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);
촉각 피드백 사용자 지정
촉각 피드백을 사용자 지정하는 세 가지 방법이 있습니다. 첫 번째는 디지털 잉크 및 상호 작용 피드백 모두에서 지원되는 반면, 두 번째와 세 번째는 상호 작용 피드백에서만 지원됩니다.
최대 시스템 강도 설정을 기준으로 피드백의 강도를 조정합니다. 이렇게 하려면 먼저 SimpleHapticsController가 강도 설정을 지원하는지 확인한 다음 원하는 값으로
Intensity
을 호출해야 합니다.if (hapticsController.IsIntensitySupported) { foreach (var waveform in hapticsController.SupportedFeedback) { if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.Click) { double intensity = 0.75; hapticsController.SendHapticFeedback(waveform, intensity); } } }
지정된 횟수만큼 촉각 신호를 반복합니다. 이렇게 하려면 먼저 SimpleHapticsController 가 강도 설정을 지원하는지 확인한 다음 원하는 개수 값으로 SendHapticFeedbackForPlayCount 를 호출해야 합니다. 강도와 재생 일시 중지 간격을 모두 설정할 수도 있습니다.
비고
SimpleHapticsController가 강도 또는 재생 일시 중지 간격 설정을 지원하지 않는 경우 제공된 값은 무시됩니다.
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); } } }
촉각 신호의 기간을 설정합니다. 이렇게 하려면 먼저 SimpleHapticsController 가 재생 기간 설정을 지원하는지 확인한 다음 원하는 시간 간격 값으로 SendHapticFeedbackForDuration 을 호출해야 합니다. 강도를 설정할 수도 있습니다.
비고
SimpleHapticsController가 강도 설정을 지원하지 않으면 제공된 값이 무시됩니다.
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); } } }
예시
다음 기능의 작동 예제를 보려면 펜 촉각 샘플을 참조하세요.
- 펜 입력에서 SimpleHapticsController 얻습니다: PointerId에서 PenDevice로 이동하고 SimpleHapticsController로 이동합니다 (촉각 지원 펜과 펜을 지원하는 장치를 모두 필요로 함).
- 펜 촉각 기능 확인: SimpleHapticsController는 IsIntensitySupported, IsPlayCountSupported, SupportedFeedback등 펜 하드웨어 기능에 대한 속성을 제공합니다.
- 촉각 피드백을 시작하고 중지하려면 SendHapticFeedback 메서드와 StopFeedback 메서드를 적절히 사용하세요.
- 촉각 피드백 트리거: 필기 피드백 및 상호 작용 피드백.
Windows developer