iT邦幫忙

2025 iThome 鐵人賽

DAY 19
3
Modern Web

從 Canvas 到各式各樣的 Web API 之旅系列 第 19

Day 19 - 滑鼠、鍵盤全接管!用 Pointer Lock API、Keyboard Lock API 做高強度互動

  • 分享至 

  • xImage
  •  

延續昨天的 EyeDropper API,我們今天來看看另外一組「輸入相關」的 Web API:Pointer Lock APIKeyboard Lock API

它們有個共同點:鎖定輸入裝置,讓瀏覽器能更沉浸、更接近遊戲體驗。


Pointer Lock API

平常滑鼠移動時,游標會受限於螢幕邊界。而 Pointer Lock API 允許我們「鎖定」滑鼠:

  • 游標會消失。
  • 移動不再是絕對位置,而是回傳「相對位移」。

這對 第一人稱遊戲 (FPS)3D 建模沉浸式體驗 都很重要。

基本用法

const area = document.getElementById("game-area");

// 點擊進入 Pointer Lock
area.addEventListener("click", () => {
  area.requestPointerLock();
});

// 監聽滑鼠移動
document.addEventListener("mousemove", (e) => {
  if (document.pointerLockElement === area) {
    console.log(`相對移動: dx=${e.movementX}, dy=${e.movementY}`);
  }
});

範例 Demo

來個好玩的範例~ 一定要玩玩看喔 🎉

  1. 點擊指定區域或按鈕 → 進入 Pointer Lock游標隱藏並回傳滑鼠「相對位移」(movementX/movementY)。
  2. 解除 Pointer Lock(按 Esc 或程式呼叫)→ 游標恢復、停止相對位移事件。

Pointer Lock


Keyboard Lock API

平常瀏覽器會攔截某些按鍵:

  • F1 → 開啟說明
  • Esc → 退出全螢幕
  • Alt+Tab → 系統切換視窗

Keyboard Lock API 允許網站「鎖定」部分鍵盤輸入,不再被瀏覽器攔截。這對:

  • 遊戲操作(需要完整的鍵位控制)
  • 自訂快捷鍵應用
    特別有用。

基本用法

// 請求鎖定指定按鍵
navigator.keyboard.lock(["F1", "Escape"]);

// 監聽鍵盤事件
window.addEventListener("keydown", (e) => {
  console.log("鍵盤輸入:", e.key);
});

// 解除鎖定
navigator.keyboard.unlock();

注意事項

  • 支援度比 Pointer Lock 更低(目前 Chrome 為主)。
  • 作業系統層級快捷鍵(例如 Alt+Tab)無法攔截,避免安全性問題。

應用場景

  1. 第一人稱射擊遊戲
    • Pointer Lock 提供滑鼠相對移動。
    • Keyboard Lock 確保 WASD、F1、Esc 都能自由運用。
  2. 3D 編輯器
    • 用滑鼠拖曳旋轉模型,鍵盤鎖定特定快捷操作。
  3. 沉浸式展示
    • 全螢幕 + 鎖定輸入 → 讓網頁體驗更接近原生應用。

瀏覽器安全考量

這兩個 API 都涉及「奪取控制權」:

  • Pointer Lock 需要使用者觸發(例如點擊)才能進入,避免網頁偷偷鎖定滑鼠。
  • Keyboard Lock 只能鎖部分按鍵,且需 HTTPS + 使用者互動。

安全性與使用者體驗是設計重點。這也讓我們看到,瀏覽器在「開放強大能力」與「避免惡意行為」之間的平衡。


小結

昨天的 EyeDropper API 是「輸入的一小步」,今天的 Pointer Lock / Keyboard Lock 則是「輸入的一大步」。

它們讓 Web 不只讀取輸入,更能鎖定輸入,創造沉浸體驗

雖然支援度不完美,但它們展示了 Web 在互動場景下的更多可能性。


👉 歡迎追蹤這個系列,我會從 Canvas 開始,一步步帶你認識更多 Web API 🎯


上一篇
Day 18 - EyeDropper API 滴管選色器
系列文
從 Canvas 到各式各樣的 Web API 之旅19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言