惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX
博客园 - 【当耐特】
WordPress大学
WordPress大学
爱范儿
爱范儿
美团技术团队
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
量子位
Hugging Face - Blog
Hugging Face - Blog
B
Blog RSS Feed
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 聂微东
H
Hackread – Cybersecurity News, Data Breaches, AI and More
腾讯CDC
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
博客园 - 叶小钗
GbyAI
GbyAI
Y
Y Combinator Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Full Disclosure
G
Google Developers Blog
D
Docker
T
Tailwind CSS Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
T
The Blog of Author Tim Ferriss
B
Blog
博客园 - 三生石上(FineUI控件)
博客园 - Franky
H
Help Net Security
MyScale Blog
MyScale Blog
U
Unit 42
D
DataBreaches.Net
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
L
LangChain Blog
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
Microsoft Security Blog
Microsoft Security Blog

程序员笔记(huoyijie.cn)

generate new dataset with llm and knowledge graph resume deepseek applications Implement the classic huarongdao game with react Implement the classic tetris game with react Writing admin dashboard template with Nextjs How to AuthN user with OpenLDAP share whiteboard with websocket ocr overview tech notes subscribe topic with sse multi devices github an algorithm used for image text detect an algorithm used for image text detect facial expression recognition technology based on neural network oauth2 mysql store a real time collaborative whiteboard with infinite space How to perform load testing with Grafana k6 fix split of undefined with gitbook theme nodejs http proxy middleware analyze referer of express website writing a CDN origin server with Django a personal lightweight CMS tool writing in Golang profile introduce the post processing introduce the text detect method blockchain for dummies medical applications on ai facial expression recognition study facial expression recognition auth auth with oauth2 auth with jwt chat with sse react chat with websocket react http message signatures infinite whiteboard with socket.io multi factor auth with totp subscribe topic with sse capture screen to gif Golang 经典入门实践教程 · GitBook EFS 加密文件系统 · GitBook 弈杰围棋智能终端 · GitBook 基于 SOCKET.IO 搭建个人电脑 HTTP 静态服务器代理 · GitBook 三百行代码搭建一个简单的 SOCKS5 代理服务器 · GitBook 微信小程序(蓝牙BLE)远程遥控树莓派小车 · GitBook 语音远程遥控树莓派小车 · GitBook 树莓派的一些使用经验 · GitBook 从零开始制作树莓派小车 · GitBook UDPack 2.0 协议 · GitBook 前言 · GitBook 升级 Ubuntu 到 20.04 LTS 长期维护版本 · GitBook 反向代理服务器实现原理 · GitBook 网站支持 HTTP 2.0 · GitBook 搭建配置邮件服务器 · GitBook 使用 Git 与 Gitbook 创建管理电子书 · GitBook 网站图片视频接入CDN · GitBook a personal lightweight self hosted git server written in Golang 快速搭建CDN回源服务器 · GitBook 基于 Git 搭建代码托管服务器 · GitBook
如何把手机触摸屏变成触控板(Touchpad) · GitBook
huoyijie · 2024-05-24 · via 程序员笔记(huoyijie.cn)

鼠标使用简单直观,掌握起来也容易,但是通过手势触控操作的触控板却受到越来越多的欢迎。鼠标移动起来需要比较大的平面空间,还需要鼠标垫,使用限制大,时间长了,手腕会累。触控板克服了这些缺陷,掌握常用的操作手势后,用起来非常方便。我的台式电脑有时会接投影仪投屏,通过鼠标操作不太方便。我就想通过一个有趣的项目,把手机触摸屏改造为遥控器来控制投影仪。

想要实现手机触控远程操作电脑鼠标,需要解决3个最重要的问题:

1. 识别手机触控手势

浏览器已有手势操作相关标准,基于 Web 天然跨平台的优势,采用浏览器来识别手势也是很自然的事情,而且有现成的开源库 hammer.js 可以直接使用。hammer.js 可以识别各种手势以及手指与屏幕的接触点坐标。

查看 hammer.js 官方 Doc,主要支持以下手势:

  • Pan - 移动/拖动

通过 Hammer.Pan(options) 可以构建一个移动手势对象,后面需要把 Hammer 实例对象关联到 Dom 的某个 element 元素上面,这个 element 即支持相应的手势操作了。需要支持哪些手势,就把相应构建好的手势对象实例添加到 Hanmmer 实例对象中即可,如 Hammer.Pan。Pan 对象接受一个 options 参数对象,主要选项如下表:

选项 默认值 说明
event pan 事件名称,Pan 实例会触发的事件,所支持的事件列表后面给出
pointers 1 与屏幕接触点数量,如果移动鼠标指针,只需为 1,如果滑动滚动条,通常需要为 2
threshold 10 识别该手势所需最小的移动距离(单位: 像素)
direction DIRECTION_ALL 移动方向,包含上、下、左、右四个方向,滑动滚动条时很有用

pan: 代表下面所有的事件都需要触发

panstart: 移动开始事件

panmove: 移动中事件

panend: 移动结束事件

pancancel: 移动取消事件

panleft: 向左移动事件

panright: 向右移动事件

panup: 向上移动事件

pandown: 向下移动事件

其中 panleft/panright 手势配合 2 个接触点可以控制滚动条左右滑动。同理,panup/pandown 手势配合 2 个接触点可以控制滚动条上下滑动。进而替代鼠标滚轮。

panstart/panmove/panend 配合 1 个接触点可以控制鼠标指针移动,如果再配合后面会提到的 press,则可以实现控制鼠标拖动。panmove 事件会实时上报接触点的绝对坐标或者相对位移,以此可以实时计算鼠标指针应该移动的方向和距离。

  • Pinch - 缩放

可以通过 2 个或更多的接触点,实现手势控制缩放,本例暂时没有用到

  • Press - 按压

可以识别 1 个或多个接触点的按压和释放手势,和 Tap 点击手势有所区别。上面提到了,press 配合 panstart/panmove/panend 可以实现鼠标拖动

选项 默认值 说明
event press 事件名称,Hammer.Press 实例会触发
pointers 1 与屏幕接触点数量,如拖动鼠标(按住左键移动鼠标),需为 1
threshold 9 按压时接触点允许移动的最大距离(单位: 像素)
time 251 识别该手势要求保持按压状态的最短时间(单位: 毫秒)

press: 按压事件 pressup: 释放事件

  • Rotate - 旋转

可以通过 2 个或更多的接触点,实现手势控制旋转,本例暂时没有用到

  • Swipe - 快速滑动

可以通过 1 个或多个接触点的快速移动,实现手势控制翻页、切换 Tab 标签页等,本例暂时没有用到

  • Tap - 点击

可以通过 1 个接触点,实现鼠标左键单击、双击、甚至三连击等,也可以通过 2 个接触点点击模拟鼠标右键点击。

选项 默认值 说明
event tap 事件名称
pointers 1 1 个接触点点击代表鼠标左键单击,2 个接触点点击代表鼠标右键单击
taps 1 识别该手势的点击次数,如果单击为 1,双击为 2
interval 300 多次点击被识别为同一个点击事件的最大时间间隔 (单位: 毫秒)
time 250 点击时按压状态保持的最大时长 (单位: 毫秒)
threshold 2 点击时所允许的接触点移动距离 (单位: 像素)
posThreshold 10 多次单击位置的最大差距距离(单位: 像素)

tap: 点击事件

2. 手机与电脑之间低时延实时通信

手机和电脑之间可以通过 WIFI 建立 TCP 连接进行通信,要求手机和电脑连接相同的 WIFI,这样彼此之间可以进行通信。可以直接通过 socket.io 开源库实现,电脑端通过 Node.js 实现服务端,手机端浏览器作为客户端。因为是内网,连接质量有所保证,注意在初始化 socket.io 服务端和客户端时,可以通过配置选项控制直接建立 websocket 连接。而且 socket.io 对断线重连有非常好的支持,意外断开连接,或者重启服务端程序,甚至短时间内重启电脑,都可以自动重新连接。

虽然电脑和手机之间的数据传输量不大,但是实时性要求非常高,尤其在鼠标移动时,需要不停的计算鼠标指针的位置并不断的移动鼠标。如果数据包延时较大,鼠标的移动控制就有顿错感,体验很差。所以实际使用手机控制电脑时,要注意手机和电脑的 WIFI 信号质量、周围是否有蓝牙或者其他相同频道的干扰信号。这些干扰信号会使得通信速度下降,造成时延增加,使得鼠标出现滞后的顿错感。同理,如果路由器设备比较老了,还在用 2.4G 频率通信,如果在观看在线视频甚至游戏场景,电脑和路由器之间的数据包很多,也可能造成手机发出的触控数据包的实时性。

最理想的情况是,家里的路由器支持 5G 信号,并且信号覆盖比较理想,电脑和手机 WIFI 信号也不错,也没有其他无线干扰信号。2.4G 频段干扰信号比较多,如蓝牙、或者无线鼠标键盘等都在这个频段,很容易和 2.4G WIFI 相互之间产生信号干扰。

当然如果给台式机单独配置一个 USB 无线网卡,单独给手机来连接,进行触控数据包的实时传输,效果应该会更好,因为数据包不在经过路由器转发,手机和电脑距离又近,体验应该非常接近于无线蓝牙鼠标了。

3. 手势数据转换为相应的鼠标操作

现在手机产生的手势数据已经实时传输到了电脑端,现在需要调用鼠标驱动程序,对鼠标进行相应的控制。幸运的是,Node.js 端有个 robotjs 开源库,就像名字所暗示的,可以通过 js 实现 robot 控制电脑,让电脑可以自主操作,实现桌面自动化。可以实现一些桌面自动化测试任务,甚至实现游戏外挂。

通过 robotjs 可以控制鼠标、键盘、显示器等。下面列出了 Mouse 的主要 API:

setMouseDelay(ms): 设置鼠标时间延时(默认 10ms)

Argument Description Default
ms 延时 (ms) None

moveMouse(x, y): 移动鼠标到 (x, y)

Argument Description Default
x x 坐标 None
y y 坐标 None

moveMouseSmooth(x, y): 模拟人类操作,移动更平滑

Argument Description Default
x x 坐标 None
y y 坐标 None

mouseClick([button], [double]): 点击鼠标

Argument Description Default
button 接受左键 'left',右键 'right', 中间滚轮键 'middle' 'left'
double 是否双击 None

mouseToggle([down], [button]): 按压鼠标

Argument Description Default
down 按下 'down',释放 'up' 'down'
button 接受左键 'left',右键 'right', 中间滚轮键 'middle' 'left'

dragMouse(x, y): 拖动鼠标到 (x, y)

Argument Description Default
x x 坐标 None
y y 坐标 None

getMousePos(): 获取当前鼠标位置

scrollMouse(x, y): 滑动滚动条

Argument Description Default
x 负数向左滑动,正数向右滑动 None
y 负数向下滑动,正数向上滑动 None

getScreenSize(): 获取屏幕分辨率 (width * height)

现在所有的积木模块都已经准备好,我们要做的事情就是把积木组装起来。因为手机端基于浏览器 html5 实现,所以需要搭建一个简单的 web app,可以基于 Koa,启动一个 web 服务非常简单,启动 web server 的同时初始化好 socket.io 服务。在 html 页面上引入 hammer.js 实现手势的识别,并通过 socket.io 连接把手势数据实时传输到服务端,服务端解析数据包,并通过 robotjs 驱动鼠标,实现对鼠标的控制。

在进行 socket.io 通信时可以参照官方文档进行性能优化,实现最佳通信性能。同时每次通信时,只传输必要的数据,减少冗余数据,数据经过二进制序列化等都可以帮助减少数据包大小,减少数据包时延,提升操控体验。

mobile-touchpad

mobile-touchpad 项目已开源,项目地址 https://github.com/huoyijie/mobile-touchpad/

安装

1.检查 Node 版本,高于此版本应该都是可以的

$ node -v
v14.16.0

$ npm -v
6.14.13

2.克隆代码

git clone https://github.com/huoyijie/mobile-touchpad.git

3.安装依赖

npm i

4.运行服务端

npm start

5.打开手机浏览器,访问 http://ip:3000,其中 ip 为电脑 ip 地址

等待页面加载完成后,就可以通过手机触控操作电脑了。