Electron/Tauri应用如何获取触控板单个触摸实现自定义手势?
回答
问题1:JavaScript能否直接访问触控板的单个触摸点?
不能。标准Web API(包括Electron渲染进程)无法获取触控板的单个触摸点原始数据:
- 浏览器会将触控板的多点触摸统一转换成系统级手势事件(如
gesturestart/gesturechange)或组合事件(如wheel+ctrlKey),不会暴露单个触摸的坐标、压力、触点ID等底层信息。 - Web的
touchstart/touchmove系列事件仅针对触摸屏设备,触控板触发的触摸不会被这些事件捕获。
问题2:可行的替代方案
方案1:Tauri + Rust 调用系统原生API(推荐)
完全匹配你的需求:保留HTML/CSS/JS实现UI,用Rust获取底层触控板数据,通过IPC传递给前端处理自定义手势。
具体实现思路:
- 在macOS上,通过Rust调用AppKit的
NSTouchAPI:可以用cacao库(AppKit的Rust绑定),或者直接用objccrate手动绑定NSTouch相关类。 - 开发Tauri插件,在插件中监听窗口触摸事件:
- 获取Tauri的原生窗口实例(macOS下对应
NSWindow)。 - 为窗口开启触摸支持(设置
acceptsTouchEvents = true)。 - 实现
NSResponder的触摸方法(如touchesBeganWithEvent:、touchesMovedWithEvent:),提取每个NSTouch的位置、阶段、触点数量等数据。 - 通过Tauri的IPC机制(
plugin::emit)将触摸数据发送给前端JS。
- 获取Tauri的原生窗口实例(macOS下对应
- 前端JS监听IPC事件,拿到原始触摸数据后,即可实现自定义多手势逻辑(同时缩放、平移、旋转等)。
简化代码示例(Rust插件部分):
use cacao::appkit::{Window, NSWindow}; use cacao::foundation::id; use objc::msg_send; use tauri::plugin::{Builder, TauriPlugin}; #[derive(Clone, serde::Serialize)] struct TouchData { x: f64, y: f64, phase: String, touch_count: usize, } fn create_touch_plugin() -> TauriPlugin { Builder::new("touchpad") .setup(|app| { let main_window = app.get_window("main").unwrap(); let ns_window: id = main_window.ns_window().unwrap() as id; // 开启窗口触摸支持 unsafe { let _: () = msg_send![ns_window, setAcceptsTouchEvents: true]; } // 此处需通过objc动态添加触摸事件处理方法,或实现cacao的Responder trait Ok(()) }) .build() }
方案2:macOS专属Swift/Objective-C应用 + WebView
如果cacao的实验性特性不符合稳定性要求,可以直接用Swift开发macOS主程序,内嵌WKWebView承载HTML/CSS/JS UI:
- 在Swift中监听
NSWindow的触摸事件,通过NSTouch获取原始数据。 - 利用WKWebView的
evaluateJavaScript()方法,将触摸数据注入前端JS环境,或通过WKScriptMessageHandler实现双向通信。 - 该方案对macOS触摸支持最完善,但属于平台专属,后续跨平台需要额外开发。
方案3:Electron原生Node.js模块(不推荐)
可以编写Electron的原生Node.js模块(用C++/Objective-C),调用AppKit的NSTouch API,再将接口暴露给渲染进程JS。但该方案需要维护Node.js原生模块的编译兼容(不同Electron版本、系统架构),复杂度远高于Tauri方案。
内容的提问来源于stack exchange,提问作者callum
相关产品推荐
相关产品推荐

