Files

337 lines
14 KiB
Markdown
Raw Permalink Normal View History

2026-05-16 13:24:02 +08:00
# 实用工具模块
<cite>
**本文引用的文件**
- [logger.js](file://client/src/logger.js)
- [log.ts](file://src/log.ts)
- [memoryhelper.js](file://client/src/memoryhelper.js)
- [charnumber.js](file://client/src/charnumber.js)
- [inputdevice.js](file://client/src/inputdevice.js)
- [pointercorrect.js](file://client/src/pointercorrect.js)
- [pointercorrect.test.js](file://client/test/pointercorrect.test.js)
- [memoryhelper.test.js](file://client/test/memoryhelper.test.js)
- [inputdevice.test.js](file://client/test/inputdevice.test.js)
- [package.json](file://package.json)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统性地文档化了“实用工具模块”,涵盖以下方面:
- 日志系统:前端简易开关式日志与后端结构化日志(含级别、时间戳、前缀格式化)。
- 内存辅助工具:按位写入字节缓冲,支持位级布尔操作与整型大小常量。
- 字符数字转换工具:按键键值映射与字符编码处理,支撑文本事件生成。
- 指针校正工具坐标变换、黑边填充Letterbox补偿、屏幕适配与输入精度优化。
文档同时提供可直接定位到源码位置的路径指引,便于在实际项目中快速集成与验证。
## 项目结构
实用工具模块位于客户端与服务端两处:
- 客户端工具位于 client/src包含日志开关、内存辅助、字符映射、输入设备状态序列化、指针校正等。
- 服务端日志位于 src/log.ts提供结构化日志级别与格式化输出。
```mermaid
graph TB
subgraph "客户端(client/src)"
LJS["logger.js<br/>前端简易日志"]
MJS["memoryhelper.js<br/>内存辅助(位写入)"]
CJS["charnumber.js<br/>字符数字映射"]
IDJS["inputdevice.js<br/>输入设备/状态/事件"]
PCJS["pointercorrect.js<br/>指针校正"]
end
subgraph "服务端(src)"
LTS["log.ts<br/>结构化日志"]
end
IDJS --> MJS
IDJS --> CJS
PCJS --> |"使用元素尺寸/布局"| 浏览器DOM["浏览器DOM/HTMLVideoElement"]
LJS -. 可独立使用 .-> 浏览器控制台
LTS -. 输出到 .-> Node控制台
```
图表来源
- [logger.js:1-30](file://client/src/logger.js#L1-L30)
- [memoryhelper.js:1-28](file://client/src/memoryhelper.js#L1-L28)
- [charnumber.js:1-110](file://client/src/charnumber.js#L1-L110)
- [inputdevice.js:1-719](file://client/src/inputdevice.js#L1-L719)
- [pointercorrect.js:1-125](file://client/src/pointercorrect.js#L1-L125)
- [log.ts:1-51](file://src/log.ts#L1-L51)
章节来源
- [logger.js:1-30](file://client/src/logger.js#L1-L30)
- [log.ts:1-51](file://src/log.ts#L1-L51)
## 核心组件
- 前端日志工具logger.js
- 提供启用/禁用与多级别输出函数,基于全局开关控制是否打印至浏览器控制台。
- 适合开发调试阶段按需开启/关闭日志输出。
- 后端日志工具log.ts
- 定义日志级别枚举与解析函数;统一格式化时间戳与级别前缀;根据级别选择对应 console 方法输出。
- 支持通过配置设置全局日志级别,实现生产环境精细化日志控制。
- 内存辅助工具memoryhelper.js
- 提供静态方法按位写入 ArrayBuffer 的指定偏移;支持置位/清位;提供整型大小常量。
- 在输入设备状态序列化中用于紧凑存储布尔标志位。
- 字符数字转换工具charnumber.js
- 提供按键键名到数值的映射表,用于文本事件生成与键盘状态记录。
- 指针校正工具pointercorrect.js
- 将浏览器坐标系映射到视频坐标系处理黑边Letterbox补偿与元素内内容矩形计算。
- 支持动态重置视频宽高与元素尺寸,适配不同播放场景。
章节来源
- [logger.js:1-30](file://client/src/logger.js#L1-L30)
- [log.ts:1-51](file://src/log.ts#L1-L51)
- [memoryhelper.js:1-28](file://client/src/memoryhelper.js#L1-L28)
- [charnumber.js:1-110](file://client/src/charnumber.js#L1-L110)
- [pointercorrect.js:1-125](file://client/src/pointercorrect.js#L1-L125)
## 架构总览
下图展示了输入设备状态序列化与文本事件生成的整体流程,体现内存辅助与字符映射在其中的关键作用。
```mermaid
sequenceDiagram
participant Dev as "输入设备"
participant State as "键盘状态"
participant Mem as "内存辅助(MemoryHelper)"
participant Text as "文本事件(TextEvent)"
Dev->>State : "按键事件(KeyboardEvent)"
State->>Mem : "按位写入(keys缓冲, 键位索引, 布尔值)"
Mem-->>State : "更新后的keys缓冲"
State-->>Text : "生成文本事件(包含InputEvent头+字符编码)"
Text-->>外部 : "序列化为ArrayBuffer"
```
图表来源
- [inputdevice.js:274-322](file://client/src/inputdevice.js#L274-L322)
- [memoryhelper.js:7-20](file://client/src/memoryhelper.js#L7-L20)
- [charnumber.js:3-109](file://client/src/charnumber.js#L3-L109)
- [inputdevice.js:620-660](file://client/src/inputdevice.js#L620-L660)
## 详细组件分析
### 日志系统(前端与后端)
- 前端简易日志logger.js
- 开关控制enable/disable 切换 isDebug 标志,后续 debug/info/log/warn/error 仅在开启时输出。
- 使用建议:开发阶段调用 enable发布版本调用 disable或结合构建脚本条件编译。
- 后端结构化日志log.ts
- 级别定义none/error/warn/log/info 五级parseLogLevel 支持字符串解析。
- 输出格式:统一 ISO 时间戳与大写级别前缀;按级别选择 console.error/warn/info/log。
- 控制策略setLogLevel 设置全局级别;当级别为 none 时不输出任何内容。
```mermaid
flowchart TD
Start(["开始"]) --> SetLevel["设置日志级别(setLogLevel)"]
SetLevel --> Parse["解析字符串级别(parseLogLevel)"]
Parse --> LogCall["log(级别, 参数...)"]
LogCall --> Check{"级别允许输出?"}
Check --> |否| Exit["结束(不输出)"]
Check --> |是| Format["格式化时间戳与级别前缀"]
Format --> Console["按级别输出(console.*)"]
Console --> Exit
```
图表来源
- [log.ts:11-24](file://src/log.ts#L11-L24)
- [log.ts:30-50](file://src/log.ts#L30-L50)
章节来源
- [logger.js:1-30](file://client/src/logger.js#L1-L30)
- [log.ts:1-51](file://src/log.ts#L1-L51)
### 内存辅助工具MemoryHelper
- 功能概述
- writeSingleBit对指定 bitOffset 的位进行置位/清位,底层通过 Uint8Array 访问目标字节。
- sizeOfInt返回整型字节数常量用于事件头与数据之间的边界计算。
- 复杂度与性能
- 单次写入为 O(1),空间开销极小;适合高频输入事件的布尔标志位压缩存储。
- 典型用法
- 在键盘/鼠标/手柄状态类中,使用该工具将布尔标志位紧凑写入缓冲区,减少带宽占用。
```mermaid
flowchart TD
S(["进入writeSingleBit"]) --> View["创建Uint8Array视图"]
View --> Index["计算字节索引(index)"]
Index --> Offset["计算位偏移(bitOffset)"]
Offset --> Load["读取原字节值(byte)"]
Load --> Mask["构造掩码(1<<bitOffset)"]
Mask --> Op{"value为真?"}
Op --> |是| Or["按位或置位"]
Op --> |否| And["按位与清位"]
Or --> Store["写回新字节"]
And --> Store
Store --> E(["退出"])
```
图表来源
- [memoryhelper.js:7-20](file://client/src/memoryhelper.js#L7-L20)
章节来源
- [memoryhelper.js:1-28](file://client/src/memoryhelper.js#L1-L28)
- [memoryhelper.test.js:1-67](file://client/test/memoryhelper.test.js#L1-L67)
### 字符数字转换工具CharNumber 与 Keymap
- CharNumber
- 将按键键名映射到数值编码,用于文本事件生成与键盘状态记录。
- Keymap
- 将 KeyboardEvent.code 映射到内部键位索引,配合 MemoryHelper 写入 keys 缓冲。
- 文本事件生成
- TextEvent.create 组合 InputEvent 头与字符编码,最终序列化为 ArrayBuffer。
```mermaid
classDiagram
class CharNumber {
+映射表
}
class Keymap {
+映射表
}
class KeyboardState {
+buffer : ArrayBuffer
+format : Number
}
class TextEvent {
+create(deviceId, event, time) TextEvent
+buffer : ArrayBuffer
}
KeyboardState --> Keymap : "键位索引"
KeyboardState --> CharNumber : "字符编码"
TextEvent --> KeyboardState : "组合InputEvent头"
```
图表来源
- [charnumber.js:3-109](file://client/src/charnumber.js#L3-L109)
- [inputdevice.js:274-322](file://client/src/inputdevice.js#L274-L322)
- [inputdevice.js:620-660](file://client/src/inputdevice.js#L620-L660)
章节来源
- [charnumber.js:1-110](file://client/src/charnumber.js#L1-L110)
- [inputdevice.js:274-322](file://client/src/inputdevice.js#L274-L322)
- [inputdevice.js:620-660](file://client/src/inputdevice.js#L620-L660)
### 指针校正工具PointerCorrector
- 功能概述
- 将浏览器坐标系clientX/Y转换为视频坐标系考虑元素内黑边Letterbox补偿与视频宽高比。
- 提供 letterBoxType、letterBoxSize、contentRect 等属性,便于精确映射。
- 关键步骤
- 原点归零:减去元素左上角偏移。
- Y轴反转浏览器坐标系向下为正视频坐标系向上为正。
- 黑边补偿:减去 letterbox 的 x/y 偏移。
- 比例映射:按 contentRect 与 video 尺寸比缩放。
- 适用场景
- 视频播放器内点击/触摸区域映射、远程输入定位、跨屏适配。
```mermaid
flowchart TD
In(["输入: [clientX, clientY]"]) --> SubOrigin["减去元素左上角偏移"]
SubOrigin --> FlipY["Y轴反转(height - y)"]
FlipY --> AddLB["减去黑边偏移(x,y)"]
AddLB --> Scale["按contentRect与video尺寸比缩放"]
Scale --> Out(["输出: [videoX, videoY]"])
```
图表来源
- [pointercorrect.js:20-40](file://client/src/pointercorrect.js#L20-L40)
- [pointercorrect.js:78-119](file://client/src/pointercorrect.js#L78-L119)
章节来源
- [pointercorrect.js:1-125](file://client/src/pointercorrect.js#L1-L125)
- [pointercorrect.test.js:1-46](file://client/test/pointercorrect.test.js#L1-L46)
## 依赖关系分析
- 输入设备模块inputdevice.js依赖
- MemoryHelper用于将布尔标志位写入缓冲。
- CharNumber用于文本事件中的字符编码。
- Keymap用于将 KeyboardEvent.code 转换为内部键位索引。
- 其他MouseButton、GamepadButton、TouchPhase、TouchFlags 等常量与枚举。
- 指针校正工具pointercorrect.js依赖
- HTMLVideoElement 的 getBoundingClientRect 获取元素尺寸与偏移。
- LetterBoxType 枚举与 contentRect 计算逻辑。
```mermaid
graph LR
ID["inputdevice.js"] --> MH["memoryhelper.js"]
ID --> CN["charnumber.js"]
ID --> KM["keymap.js"]
ID --> MB["mousebutton.js"]
ID --> GPB["gamepadbutton.js"]
ID --> TP["touchphase.js"]
ID --> TF["touchflags.js"]
PC["pointercorrect.js"] --> DOM["HTMLVideoElement<br/>getBoundingClientRect()"]
```
图表来源
- [inputdevice.js:1-10](file://client/src/inputdevice.js#L1-L10)
- [pointercorrect.js:12-14](file://client/src/pointercorrect.js#L12-L14)
章节来源
- [inputdevice.js:1-719](file://client/src/inputdevice.js#L1-L719)
- [pointercorrect.js:1-125](file://client/src/pointercorrect.js#L1-L125)
## 性能考量
- 内存辅助MemoryHelper
- O(1) 位写入,适合高频输入事件;注意避免频繁创建 ArrayBuffer复用现有缓冲可降低分配开销。
- 日志输出
- 前端isDebug 控制,避免在生产环境输出;建议在打包阶段移除调试日志以减少运行时开销。
- 后端:通过 setLogLevel 限制输出级别,生产环境建议仅输出 error/warn格式化字符串与级别前缀为常量开销可控。
- 指针校正
- map 为纯数学运算复杂度低letterBoxType/letterBoxSize/contentRect 可缓存于实例字段,减少重复计算。
## 故障排查指南
- 日志不输出
- 前端:确认已调用 enable检查 isDebug 是否被其他逻辑覆盖。
- 后端:确认 setLogLevel 已正确设置;若级别为 none则不会输出任何内容。
- 文本事件字符异常
- 检查 CharNumber 中是否存在目标键名映射;确保 KeyboardEvent.key 与映射一致。
- 指针映射不准
- 确认 HTMLVideoElement 的尺寸与样式(如 object-fit未引入额外缩放必要时在 PointerCorrector.reset 中传入最新尺寸。
- 验证 letterBoxType 与 letterBoxSize 计算结果是否符合预期。
章节来源
- [logger.js:1-30](file://client/src/logger.js#L1-L30)
- [log.ts:11-24](file://src/log.ts#L11-L24)
- [pointercorrect.test.js:1-46](file://client/test/pointercorrect.test.js#L1-L46)
- [memoryhelper.test.js:1-67](file://client/test/memoryhelper.test.js#L1-L67)
## 结论
本实用工具模块围绕“日志、内存、字符、指针”四大主题,提供了简洁高效的实现:
- 日志系统兼顾前端与后端,满足开发与生产的差异化需求;
- 内存辅助工具以位级写入为核心,支撑输入事件的紧凑序列化;
- 字符数字转换工具完善了键盘事件到内部表示的映射;
- 指针校正工具解决了视频播放场景下的坐标适配问题。
建议在实际项目中:
- 将日志级别纳入构建配置,按环境自动切换;
- 在输入设备状态序列化中优先使用 MemoryHelper 进行位级压缩;
- 对文本事件生成进行单元测试覆盖,保证字符映射一致性;
- 在视频播放器中使用 PointerCorrector 进行坐标映射与黑边补偿。
## 附录
### 使用示例(路径指引)
- 启用前端调试日志
- 参考:[logger.js:3-9](file://client/src/logger.js#L3-L9)
- 设置后端日志级别
- 参考:[log.ts:11-24](file://src/log.ts#L11-L24)
- 生成文本事件
- 参考:[inputdevice.js:639-646](file://client/src/inputdevice.js#L639-L646)
- 按位写入布尔标志
- 参考:[memoryhelper.js:7-20](file://client/src/memoryhelper.js#L7-L20)
- 指针坐标映射
- 参考:[pointercorrect.js:20-40](file://client/src/pointercorrect.js#L20-L40)
### 测试参考
- 指针校正单元测试
- 参考:[pointercorrect.test.js:1-46](file://client/test/pointercorrect.test.js#L1-L46)
- 内存辅助单元测试
- 参考:[memoryhelper.test.js:1-67](file://client/test/memoryhelper.test.js#L1-L67)
- 输入设备与文本事件测试
- 参考:[inputdevice.test.js:135-144](file://client/test/inputdevice.test.js#L135-L144)