MDN pointer events: https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events
μΉ μ ν리μΌμ΄μ μμ λ©ν° ν°μΉλ₯Ό ꡬννλ €λ©΄ ν°μΉ μ΄λ²€νΈ νΉμ ν¬μΈν° μ΄λ²€νΈλ₯Ό νμ©ν΄μΌ ν©λλ€.
μΉμμ ν°μΉ μ λ ₯μ μ²λ¦¬ν λ ν¬μΈν° μ΄λ²€νΈ(Pointer Events) μ ν°μΉ μ΄λ²€νΈ(Touch Events) μ€ νλλ₯Ό μ νν μ μλλ°, λ λ°©μ λͺ¨λ λ©ν° ν°μΉμ μ μ€μ² κ°μ§λ₯Ό μ§μνμ§λ§ μ°¨μ΄μ μ΄ μμ΅λλ€.
Touch eventsλ ν°μΉ μ€ν¬λ¦°μμ λ°μνλ μ΄λ²€νΈμ΄λ―λ‘ λͺ¨λ°μΌμμλ§ μ¬μ©νλ μ±μ κ²½μ°μ μ μ ν©λλ€. Pointer Eventsλ ν°μΉ, λ§μ°μ€, μ€νμΌλ¬μ€(ν) μ λ ₯μ ν DOM μ΄λ²€νΈμμ μ λΆ λ€λ£° μ μμ΅λλ€.
PointerEvent κ°μ²΄λ MouseEventμ λͺ¨λ μμ±μ μμλ°κ³ , pressure, contact geometry, tiltμ κ°μ μΆκ° μμ±μ κ°μ§κ³ μμ΅λλ€.
ν°μΉλ₯Ό κ°μ§ν μ μλ κΈ°κΈ°
νΉμ κΈ°κΈ°μ μ’ μλμ§ μκ³ , μ€ν¬λ¦°μ νΉμ μ’ν(νΉμ μ’νλ€)μ μ νν μ μλ μ λ ₯
νΉμ μμμ pointer μ΄λ²€νΈλ₯Ό μ¬νκ²ν ν μ μμ΅λλ€. μλ₯Ό λ€μ΄ pointer down μ DOMμ μμλ₯Ό appendνκ³ κ³μν΄μ Pointer Eventλ₯Ό λ°κ²νκ³ μΆλ€λ©΄, setPointerCaptureμ pointer idλ₯Ό μ¬μ©ν μ μμ΅λλ€. μ΄λ releasePointerCaptureλ₯Ό μ¬μ©ν΄ ν΄μ ν μ μμ΅λλ€.
μ ν νμ¬κ³Ό κ°μ μ€νμΌλ¬μ€κ° νλ©΄μ λΏμ λ, μ€νμΌλ¬μ€μ μΆμ΄ νλ©΄μ X-Y νλ©΄κ³Ό μ΄λ£¨λ κ°λ (ν¬μΈν°κ° νλ©΄μ μΌλ§λ κΈ°μΈμ΄μ‘λμ§)
ν¬μΈν°μ μΆμ΄ Y-Z νλ©΄κ³Ό ν¬μΈν° μΆ λ° Y μΆμ ν¬ν¨νλ νλ©΄ μ¬μ΄μ κ°λ (ν¬μΈν°κ° μΌλ§λ νμ νλμ§)
ν¬μΈν° μ΄λ²€νΈλ₯Ό μμ±ν ν¬μΈν μ₯μΉμ κ³ μ ID
λ°μ ν¬μΈν° μ΄λ²€νΈμ κ³ μ μλ³μ
ν¬μΈν°κ° μ μ΄ν X, Yμ λν px λ¨μ ν¬κΈ°
ν¬μΈν°κ° νλ©΄μ μ§μ μ μΌλ‘ λλ₯΄λ νμ λνλ λλ€. (0μμ 1 μ¬μ΄, 0μ μ΅μ μλ ₯, 1μ μ΅λ μλ ₯)
ν¬μΈν°κ° νλ©΄μ μνμΌλ‘ κ°νλ μλ ₯, μ¦ μΈ‘λ©΄ μλ ₯μ μΈ‘μ ν©λλ€. μ΄λ ν¬μΈν°μ μΆμ μ€μ¬μΌλ‘ μμΌλ‘ λ리λ νμ μλ―Έν©λλ€. (-1μμ 1, 0μ μ€λ¦½)
ν¬μΈν°μ μ£Όμ μΆμ μ€μ¬μΌλ‘ μκ³ λ°©ν₯μΌλ‘ νμ ν μ λ(0μμ 359λ).
μ΄λ²€νΈλ₯Ό λ°μμν¨ μ₯μΉμ μ ν
"mouse", "touch", "pen"(stylus), ""(λΈλΌμ°μ μμ μ§μνμ§ μμ)
λ©ν° ν¬μΈνΈ μλ리μ€μμ, νμ¬ ν¬μΈν°κ° ν΄λΉ ν¬μΈν° μ νμ κΈ°λ³Έ ν¬μΈν°μΈμ§ μ¬λΆ
μλ₯Ό λ€μ΄, λ§μ°μ€μ ν°μΉμ€ν¬λ¦°μ ν¨κ» μ¬μ©ν λ μ ν리μΌμ΄μ μ΄ μ£Όμ ν¬μΈν°λ§ μ§μνκ³ , μ£Όμ ν¬μΈν°κ° μλ λͺ¨λ ν¬μΈν° μ΄λ²€νΈλ₯Ό 무μνλλ‘ μμ±ν μ μμ΅λλ€
Pointer Eventλ μ΄ 10κ°μ μ΄λ²€νΈμ 1κ°μ μ€νμ μ΄λ²€νΈλ₯Ό κ°μ§κ³ μμ΅λλ€. μ΄ μ€ 7κ°λ λ§μ°μ€ μ΄λ²€νΈμ λμν©λλ€. (down, up, move, over, out, enter, leave)
| μ΄λ²€νΈ | μ€λͺ | μν© |
|---|---|---|
| pointerdown | ν¬μΈν°κ° λ²νΌ νμ± μνλ‘ λ³ν λ λ°μ | ν΄λ¦/ν°μΉ μμ |
| pointerup | ν¬μΈν°κ° λ μ΄μ νμ± μνκ° μλ λ λ°μ | ν΄λ¦/ν°μΉ λ |
| pointermove | ν¬μΈν°μ μ’ν λ³κ²½ μ λ°μ | λ§μ°μ€/ν°μΉ μ΄λ |
| pointerover | ν¬μΈν°κ° μμμ hit test κ²½κ³μ λ€μ΄μ¬ λ λ°μ | λ§μ°μ€/μκ°λ½μ΄ μμλ‘ λ€μ΄μ¬ λ |
| pointerout | ν¬μΈν°κ° μμμ hit test κ²½κ³μμ λκ° λ λ°μ | λ§μ°μ€/μκ°λ½μ΄ μμλ₯Ό λ²μ΄λ λ |
| pointerenter | ν¬μΈν°κ° μμ λλ μμ μμμ hit test κ²½κ³μ λ€μ΄μ¬ λ λ°μ | λ§μ°μ€/μκ°λ½μ΄ μμμ λΏμ λ |
| pointerleave | ν¬μΈν°κ° μμμ hit test κ²½κ³μμ λκ° λ λ°μ | λ§μ°μ€/μκ°λ½μ΄ μμμμ λ²μ΄λ λ |
| pointercancel | λΈλΌμ°μ κ° ν¬μΈν°κ° λ μ΄μ μ΄λ²€νΈλ₯Ό λ°μμν¬ μ μλ€κ³ νλ¨ν λ λ°μ | μ₯μΉ λΉνμ±ν |
| gotpointercapture | μμκ° pointer captureλ₯Ό λ°μμ λ λ°μ | pointer capture μμ |
| lostpointercapture | pointer captureκ° ν΄μ λ λ λ°μ | pointer capture ν΄μ |
| pointerrawupdate | ν¬μΈν°κ° pointerdown/up μΈ μμ±μμ λ³κ²½ μ λ°μ (μ€νμ ) | νμ μλ ₯/κΈ°μΈκΈ° λ³ν μ |
| λ©μλ | μ€λͺ |
|---|---|
| setPointerCapture() | νΉμ μμλ₯Ό λ―Έλμ ν¬μΈν° μ΄λ²€νΈμ λν pointer capture λμμΌλ‘ μ§μ ν©λλ€. |
| releasePointerCapture() | νΉμ ν¬μΈν° μ΄λ²€νΈμ λν΄ μ΄μ μ μ€μ λ pointer captureλ₯Ό ν΄μ ν©λλ€. |
| hasPointerCapture() | μ£Όμ΄μ§ pointer idμ λν΄ pointer captureκ° μ€μ λ μμμΈμ§ νμΈν©λλ€. |
Navigator.maxTouchPointsλ μ₯μΉκ° λμμ μ§μν μ μλ μ΅λ ν°μΉ ν¬μΈνΈ μλ₯Ό νμΈνλ λ° μ¬μ©λλ μμ±μ λλ€. μ΄ μμ±μ ν°μΉμ€ν¬λ¦° μ₯μΉμμ μ¬λ¬ μκ°λ½μ λμμ μΈμν μ μλ μ΅λ μλ₯Ό λ°νν©λλ€.
if (navigator.maxTouchPoints > 1) {
console.log('μ΄ μ₯μΉλ λ©ν° ν°μΉλ₯Ό μ§μν©λλ€');
} else {
console.log('μ΄ μ₯μΉλ λ©ν° ν°μΉλ₯Ό μ§μνμ§ μμ΅λλ€ == ν°μΉ κΈ°λ° μ
λ ₯μ μ§μνμ§ μμ');
}
DOMμ κ·Έλ €μ§ target μμμ μ΄λ²€νΈ νΈλ€λ¬λ₯Ό ꡬλ ν©λλ€.
<div id="target">Touch meβ¦</div>
function over_handler(event) {}
function enter_handler(event) {}
function down_handler(event) {}
function move_handler(event) {}
function up_handler(event) {}
function cancel_handler(event) {}
function out_handler(event) {}
function leave_handler(event) {}
function rawUpdate_handler(event) {}
function gotCapture_handler(event) {}
function lostCapture_handler(event) {}
function init() {
const el = document.getElementById("target");
// Register pointer event handlers
el.onpointerover = over_handler;
el.onpointerenter = enter_handler;
el.onpointerdown = down_handler;
el.onpointermove = move_handler;
el.onpointerup = up_handler;
el.onpointercancel = cancel_handler;
el.onpointerout = out_handler;
el.onpointerleave = leave_handler;
el.onpointerrawupdate = rawUpdate_handler;
el.ongotpointercapture = gotCapture_handler;
el.onlostpointercapture = lostCapture_handler;
}
document.addEventListener("DOMContentLoaded", init);
function down_handler(ev) {
// ν¬μΈνΈ μ΄λ²€νΈμ λ©΄μ κ³μ°
const area = ev.width * ev.height;
// νμ¬ μ΄λ²€νΈμ idκ° μΊμλμ΄ μλ μ§ νμΈ
if (id === ev.identifier) process_id(ev);
// pointerTypeμ λ°λ₯Έ νΈλ€λ¬ νΈμΆ
switch (ev.pointerType) {
case "mouse":
process_mouse(ev);
break;
case "pen":
process_pen(ev);
break;
case "touch":
process_touch(ev);
break;
default:
console.log(`pointerType ${ev.pointerType} is not supported`);
}
// tilt νΈλ€λ¬ νΈμΆ
if (ev.tiltX !== 0 && ev.tiltY !== 0) process_tilt(ev.tiltX, ev.tiltY);
// pressure νΈλ€λ¬ νΈμΆ
process_pressure(ev.pressure);
// λ©ν° ν¬μΈν°μ κ²½μ°, primary νΈλ€λ¬κ° μλ κ²½μ°μ νΈλ€λ¬ νΈμΆ
if (!ev.isPrimary) process_non_primary(ev);
}
function init() {
const el = document.getElementById("target");
// DOM μμμ μ΄λ²€νΈ ꡬλ
el.onpointerdown = down_handler;
}
document.addEventListener("DOMContentLoaded", init);
λ§μ°μ€μ ν λ±μ κΈ°κΈ°λ μ¬λ¬κ°μ λ²νΌμ κ°μ§κ³ μμ΅λλ€. buttonκ³Ό buttons μμ±μ ν΅ν΄μ μ΄λ€ λ²νΌμ΄ λλ Έλ μ§ νμΈν μ μμ΅λλ€.
| μν | button | buttons |
|---|---|---|
| λ²νΌμ΄λ ν°μΉ/ν μ μ΄μ΄ λ§μ§λ§ μ΄λ²€νΈ μ΄ν λ³κ²½λμ§ μμ | -1 | β |
| λ²νΌμ΄ λλ¦¬μ§ μμ μνμμ λ§μ°μ€κ° μμ§μ΄κ±°λ, λ²νΌμ΄ λλ¦¬μ§ μμ μνμμ νμ΄ νΈλ² μ€μΌ λ | β | 0 |
| μΌμͺ½ λ§μ°μ€, ν°μΉ μ μ΄, ν μ μ΄ | 0 | 1 |
| κ°μ΄λ° λ§μ°μ€ | 1 | 4 |
| μ€λ₯Έμͺ½ λ§μ°μ€, ν λ°°λ΄ λ²νΌ | 2 | 2 |
| X1 (λ€λ‘) λ§μ°μ€ | 3 | 8 |
| X2 (μμΌλ‘) λ§μ°μ€ | 4 | 16 |
| ν μ§μ°κ° λ²νΌ | 5 | 32 |
ν¬μΈν° μΊ‘μ²λ νΉμ ν¬μΈν° μ΄λ²€νΈκ° ν¬μΈν°μ μμΉμμ κΈ°μ‘΄ hit test λμ μ νΉμ μμλ‘ μ¬νκ²ν λλλ‘ ν©λλ€. λ§μ½ ν¬μΈν° μ₯μΉμ μ μ΄μ΄ μμλ₯Ό λ²μ΄λλλΌλ(μ€ν¬λ‘€μ΄λ ν¬μΌλ‘ μ΄λ) ν΄λΉ μμκ° κ³μν΄μ ν¬μΈν° μ΄λ²€νΈλ₯Ό λ°μ μ μλλ‘ ν©λλ€.
ν¬μΈν° μΊ‘μ²λ νκ² μμκ° μ΄νμ ν¬μΈν° μ΄λ²€νΈλ₯Ό λ§μΉ κ·Έ μμμμ μΌμ΄λ κ²μ²λΌ μΊ‘μ²ν μ μκ² νκΈ° λλ¬Έμ, μΊ‘μ²κ° μ€μ λλ©΄ pointerover, pointerenter, pointerleave, pointerout μ΄λ²€νΈκ° λ°μνμ§ μμ΅λλ€.
ν°μΉμ€ν¬λ¦° λΈλΌμ°μ μμλ pointerdown μ΄λ²€νΈκ° νΈλ¦¬κ±°λ λ ν΄λΉ μμμ μμμ μΌλ‘ ν¬μΈν° μΊ‘μ²κ° μ€μ λ©λλ€. μΊ‘μ²λ pointerup λλ pointercancel μ΄λ²€νΈ ν μλμΌλ‘ ν΄μ λκ³ , element.releasePointerCaptureλ₯Ό νΈμΆνμ¬ μλμΌλ‘ ν΄μ ν μ μμ΅λλ€.
button {
touch-action: none; // ν°μΉ λμμ μ μ©νμ§ μμ
}
#target {
touch-action: pan-x; // pan-xλ₯Ό μ μΈν ν°μΉ λμ μ ν
}
touch-action CSS μμ±μ λΈλΌμ°μ κ° νΉμ μμμ λν΄ λ€μ΄ν°λΈ ν°μΉ λμ(μ: νλ/μΆμ λλ μ€ν¬λ‘€)μ μ μ©ν μ§ μ¬λΆλ₯Ό μ§μ νλ λ° μ¬μ©λ©λλ€.
ν¬μΈν° μ΄λ²€νΈ μΈν°νμ΄μ€λ ν¬μΈν°κ° κ°λ₯ν μ₯μΉμμ ν₯μλ μ¬μ©μ κ²½νμ λ§λ€ μ μκ² ν΄μ£Όμ§λ§, μΉ μ½ν μΈ μ λλΆλΆμ λ§μ°μ€ μ λ ₯μ λ§μΆ° μ€κ³λ κ²½μ°κ° λ§μ΅λλ€.
μ΄μμ μΌλ‘λ Ponter Eventsκ° κ°λ₯ν μ ν리μΌμ΄μ μ λ§μ°μ€ μ λ ₯μ λͺ μμ μΌλ‘ μ²λ¦¬ν νμκ° μμ΅λλ€. pointerdown μ΄λ²€νΈλ₯Ό μ·¨μν¨μΌλ‘μ¨ νΉμ λ§μ°μ€ μ΄λ²€νΈμ μμ±μ λ°©μ§ν μ μμ§λ§, μλμ κ°μ λͺ κ°μ§ λ¬Έμ μ μ΄ μκΈΈ μ μμ΅λλ€.
μ΄λ²€νΈ νΈλ€λ¬ λ΄μμ λ무 λ§μ μμ μ μννλ©΄ μ±λ₯ μ νκ° λ°μν μ μμ΅λλ€. κ°λ₯ν ν μ΄λ²€νΈ νΈλ€λ¬ λ΄μ μμ μ κ°κ²°νκ² μ μ§νμΈμ.
μ΄λ²€νΈ νΈλ€λ¬λ₯Ό λ¬Έμ μ 체λ μμ λ Έλμ μΆκ°νλ κ²λ³΄λ€λ, νΉμ λμ μμμ μΆκ°νλ κ²μ΄ μ’μ΅λλ€. μ΄λ κ² νλ©΄ μ΄λ²€νΈ μ²λ¦¬μ ν¨μ¨μ±μ λμΌ μ μμ΅λλ€.
λμ μμ(λ Έλ)μ ν¬κΈ°λ κ°μ₯ ν° μ μ΄ νλ©΄ μμμ μμ©ν μ μμ λ§νΌ μΆ©λΆν μ»€μΌ ν©λλ€ (μκ°λ½ ν°μΉκ° κ°λ₯ν΄μΌν¨).
λ§μ½ λμ μμμ΄ λ무 μμΌλ©΄, ν΄λΉ μμλ₯Ό ν°μΉνμ λ μΈμ ν λ€λ₯Έ μμμ μ΄λ²€νΈκ° λ°μν μ μμ΅λλ€.