# 实用工具模块 **本文引用的文件** - [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) ## 目录 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
前端简易日志"] MJS["memoryhelper.js
内存辅助(位写入)"] CJS["charnumber.js
字符数字映射"] IDJS["inputdevice.js
输入设备/状态/事件"] PCJS["pointercorrect.js
指针校正"] end subgraph "服务端(src)" LTS["log.ts
结构化日志"] 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< 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
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)