Files
2026-05-16 13:24:02 +08:00

337 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实用工具模块
<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)