Tương tác đa chạm
Pointer events có thể được sử dụng để xử lý các tương tác đa chạm. Hướng dẫn này mô tả cách sử dụng pointer events để hỗ trợ tương tác đa chạm.
Theo dõi nhiều điểm chạm
Không giống với mouse events, pointer events hỗ trợ nhiều điểm chạm hoạt động đồng thời. Mỗi điểm chạm được xác định bởi thuộc tính pointerId duy nhất.
js
const activePointers = new Map();
element.addEventListener("pointerdown", (ev) => {
// Lưu trữ thông tin điểm chạm mới
activePointers.set(ev.pointerId, {
x: ev.clientX,
y: ev.clientY,
type: ev.pointerType,
});
console.log(`Active pointers: ${activePointers.size}`);
});
element.addEventListener("pointermove", (ev) => {
if (!activePointers.has(ev.pointerId)) return;
// Cập nhật vị trí
activePointers.set(ev.pointerId, {
x: ev.clientX,
y: ev.clientY,
type: ev.pointerType,
});
});
element.addEventListener("pointerup", (ev) => {
activePointers.delete(ev.pointerId);
});
element.addEventListener("pointercancel", (ev) => {
activePointers.delete(ev.pointerId);
});
Nhận diện cử chỉ kéo
Cử chỉ kéo (pan) di chuyển nội dung theo hướng ngón tay di chuyển.
js
let startX, startY;
let startScrollX, startScrollY;
element.addEventListener("pointerdown", (ev) => {
if (activePointers.size === 0) {
startX = ev.clientX;
startY = ev.clientY;
startScrollX = element.scrollLeft;
startScrollY = element.scrollTop;
}
activePointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY });
element.setPointerCapture(ev.pointerId);
});
element.addEventListener("pointermove", (ev) => {
if (activePointers.size === 1) {
// Một ngón tay: kéo
const dx = ev.clientX - startX;
const dy = ev.clientY - startY;
element.scrollLeft = startScrollX - dx;
element.scrollTop = startScrollY - dy;
}
activePointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY });
});
Nhận diện cử chỉ kẹp zoom
Cử chỉ kẹp zoom (pinch-to-zoom) dùng hai ngón tay để phóng to/thu nhỏ nội dung.
js
let initialDistance = null;
let initialScale = 1;
let currentScale = 1;
function getDistance(touches) {
const [t1, t2] = [...touches.values()];
return Math.sqrt(Math.pow(t2.x - t1.x, 2) + Math.pow(t2.y - t1.y, 2));
}
element.addEventListener("pointermove", (ev) => {
activePointers.set(ev.pointerId, { x: ev.clientX, y: ev.clientY });
if (activePointers.size === 2) {
const distance = getDistance(activePointers);
if (initialDistance === null) {
initialDistance = distance;
initialScale = currentScale;
}
currentScale = initialScale * (distance / initialDistance);
element.style.transform = `scale(${currentScale})`;
}
});
element.addEventListener("pointerup", (ev) => {
activePointers.delete(ev.pointerId);
if (activePointers.size < 2) {
initialDistance = null;
}
});