interaction-system 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +377 -0
  2. package/USAGE.md +490 -0
  3. package/dist/index.cjs.js +1983 -0
  4. package/dist/index.cjs.js.map +1 -0
  5. package/dist/index.d.ts +34 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.es.js +1983 -0
  8. package/dist/index.es.js.map +1 -0
  9. package/dist/input/KeyEvent.d.ts +315 -0
  10. package/dist/input/KeyEvent.d.ts.map +1 -0
  11. package/dist/input/KeyInputHandler.d.ts +15 -0
  12. package/dist/input/KeyInputHandler.d.ts.map +1 -0
  13. package/dist/input/KeyToCodeMap.d.ts +2 -0
  14. package/dist/input/KeyToCodeMap.d.ts.map +1 -0
  15. package/dist/input/UIEventsCode.d.ts +175 -0
  16. package/dist/input/UIEventsCode.d.ts.map +1 -0
  17. package/dist/interaction/FeaturedInteractionHandler.d.ts +26 -0
  18. package/dist/interaction/FeaturedInteractionHandler.d.ts.map +1 -0
  19. package/dist/interaction/InteractionHandler.d.ts +86 -0
  20. package/dist/interaction/InteractionHandler.d.ts.map +1 -0
  21. package/dist/interaction/SimpleInteractionHandler.d.ts +19 -0
  22. package/dist/interaction/SimpleInteractionHandler.d.ts.map +1 -0
  23. package/dist/messages/CommandControlMessage.d.ts +49 -0
  24. package/dist/messages/CommandControlMessage.d.ts.map +1 -0
  25. package/dist/messages/ControlMessage.d.ts +25 -0
  26. package/dist/messages/ControlMessage.d.ts.map +1 -0
  27. package/dist/messages/KeyCodeControlMessage.d.ts +24 -0
  28. package/dist/messages/KeyCodeControlMessage.d.ts.map +1 -0
  29. package/dist/messages/ScrollControlMessage.d.ts +23 -0
  30. package/dist/messages/ScrollControlMessage.d.ts.map +1 -0
  31. package/dist/messages/TextControlMessage.d.ts +19 -0
  32. package/dist/messages/TextControlMessage.d.ts.map +1 -0
  33. package/dist/messages/TouchControlMessage.d.ts +44 -0
  34. package/dist/messages/TouchControlMessage.d.ts.map +1 -0
  35. package/dist/models/MotionEvent.d.ts +18 -0
  36. package/dist/models/MotionEvent.d.ts.map +1 -0
  37. package/dist/models/Point.d.ts +14 -0
  38. package/dist/models/Point.d.ts.map +1 -0
  39. package/dist/models/Position.d.ts +17 -0
  40. package/dist/models/Position.d.ts.map +1 -0
  41. package/dist/models/Rect.d.ts +22 -0
  42. package/dist/models/Rect.d.ts.map +1 -0
  43. package/dist/models/ScreenInfo.d.ts +14 -0
  44. package/dist/models/ScreenInfo.d.ts.map +1 -0
  45. package/dist/models/Size.d.ts +21 -0
  46. package/dist/models/Size.d.ts.map +1 -0
  47. package/dist/types/PlayerInterface.d.ts +20 -0
  48. package/dist/types/PlayerInterface.d.ts.map +1 -0
  49. package/dist/utils/Util.d.ts +26 -0
  50. package/dist/utils/Util.d.ts.map +1 -0
  51. package/package.json +56 -0
package/USAGE.md ADDED
@@ -0,0 +1,490 @@
1
+ # Interaction System 使用指南
2
+
3
+ 本文档提供 interaction-system 库的详细使用说明和最佳实践。
4
+
5
+ ## 目录
6
+
7
+ - [快速开始](#快速开始)
8
+ - [核心概念](#核心概念)
9
+ - [完整示例](#完整示例)
10
+ - [构建工具配置](#构建工具配置)
11
+ - [API 参考](#api-参考)
12
+ - [常见问题](#常见问题)
13
+
14
+ ## 快速开始
15
+
16
+ ### 1. 安装依赖
17
+
18
+ ```bash
19
+ # 如果使用 npm link
20
+ cd interaction-system && npm link
21
+ cd your-project && npm link interaction-system
22
+
23
+ # 或者使用 file: 协议
24
+ npm install file:../path/to/interaction-system
25
+ ```
26
+
27
+ ### 2. 基本设置
28
+
29
+ ```typescript
30
+ import {
31
+ FeaturedInteractionHandler,
32
+ InteractionHandlerListener,
33
+ ControlMessage,
34
+ ScreenInfo,
35
+ Rect,
36
+ Size,
37
+ IPlayer
38
+ } from 'interaction-system';
39
+
40
+ // 实现 IPlayer 接口
41
+ class VideoPlayer implements IPlayer {
42
+ private canvas: HTMLCanvasElement;
43
+ private screenInfo?: ScreenInfo;
44
+
45
+ constructor(canvas: HTMLCanvasElement) {
46
+ this.canvas = canvas;
47
+ }
48
+
49
+ getTouchableElement(): HTMLCanvasElement {
50
+ return this.canvas;
51
+ }
52
+
53
+ getScreenInfo(): ScreenInfo | undefined {
54
+ return this.screenInfo;
55
+ }
56
+
57
+ setScreenInfo(info: ScreenInfo) {
58
+ this.screenInfo = info;
59
+ }
60
+ }
61
+
62
+ // 创建 canvas 元素
63
+ const canvas = document.createElement('canvas');
64
+ canvas.width = 360;
65
+ canvas.height = 640;
66
+ document.body.appendChild(canvas);
67
+
68
+ // 初始化播放器
69
+ const player = new VideoPlayer(canvas);
70
+
71
+ // 设置屏幕信息
72
+ const screenInfo = new ScreenInfo(
73
+ new Rect(0, 0, 1080, 1920),
74
+ new Size(1080, 1920),
75
+ 0
76
+ );
77
+ player.setScreenInfo(screenInfo);
78
+
79
+ // 创建消息监听器
80
+ const listener: InteractionHandlerListener = {
81
+ sendMessage: (message: ControlMessage) => {
82
+ console.log('控制消息:', message.toString());
83
+ const buffer = message.toBuffer();
84
+ // 发送到服务器
85
+ // websocket.send(buffer);
86
+ }
87
+ };
88
+
89
+ // 创建交互处理器
90
+ const handler = new FeaturedInteractionHandler(player, listener);
91
+
92
+ // 清理(当不再需要时)
93
+ // handler.release();
94
+ ```
95
+
96
+ ## 核心概念
97
+
98
+ ### IPlayer 接口
99
+
100
+ `IPlayer` 是交互系统的核心接口,定义了与播放器交互的契约:
101
+
102
+ ```typescript
103
+ interface IPlayer {
104
+ // 获取用于捕获交互事件的 canvas 元素
105
+ getTouchableElement(): HTMLCanvasElement;
106
+
107
+ // 获取当前屏幕信息(用于坐标转换)
108
+ getScreenInfo(): ScreenInfo | undefined;
109
+ }
110
+ ```
111
+
112
+ ### ScreenInfo
113
+
114
+ 屏幕信息用于将浏览器坐标转换为设备坐标:
115
+
116
+ ```typescript
117
+ const screenInfo = new ScreenInfo(
118
+ new Rect(0, 0, 1080, 1920), // 内容区域
119
+ new Size(1080, 1920), // 视频尺寸
120
+ 0 // 设备旋转(0, 1, 2, 3)
121
+ );
122
+ ```
123
+
124
+ ### 控制消息
125
+
126
+ 所有交互都会转换为控制消息:
127
+
128
+ - **TouchControlMessage** - 触摸事件
129
+ - **ScrollControlMessage** - 滚动事件
130
+ - **KeyCodeControlMessage** - 键盘按键
131
+ - **TextControlMessage** - 文本输入
132
+ - **CommandControlMessage** - 系统命令
133
+
134
+ ## 完整示例
135
+
136
+ ### 示例 1: 基础触摸交互
137
+
138
+ ```typescript
139
+ import {
140
+ FeaturedInteractionHandler,
141
+ TouchControlMessage,
142
+ MotionEvent
143
+ } from 'interaction-system';
144
+
145
+ // ... 设置 player 和 listener ...
146
+
147
+ const handler = new FeaturedInteractionHandler(player, {
148
+ sendMessage: (message) => {
149
+ if (message instanceof TouchControlMessage) {
150
+ const { action, pointerId, position } = message;
151
+ console.log(`触摸事件: ${
152
+ action === MotionEvent.ACTION_DOWN ? '按下' :
153
+ action === MotionEvent.ACTION_UP ? '抬起' : '移动'
154
+ } at (${position.point.x}, ${position.point.y})`);
155
+ }
156
+ // 发送到服务器
157
+ }
158
+ });
159
+ ```
160
+
161
+ ### 示例 2: 键盘输入
162
+
163
+ ```typescript
164
+ import { KeyInputHandler, KeyEventListener } from 'interaction-system';
165
+
166
+ const keyListener: KeyEventListener = {
167
+ onKeyEvent: (event) => {
168
+ console.log(`键码: ${event.keycode}, 动作: ${event.action}`);
169
+ const buffer = event.toBuffer();
170
+ // websocket.send(buffer);
171
+ }
172
+ };
173
+
174
+ // 注册全局键盘监听
175
+ KeyInputHandler.addEventListener(keyListener);
176
+
177
+ // 移除监听(清理时)
178
+ // KeyInputHandler.removeEventListener(keyListener);
179
+ ```
180
+
181
+ ### 示例 3: 简化版交互处理器
182
+
183
+ ```typescript
184
+ import {
185
+ SimpleInteractionHandler,
186
+ TouchHandlerListener,
187
+ Position
188
+ } from 'interaction-system';
189
+
190
+ const listener: TouchHandlerListener = {
191
+ performClick: (position: Position) => {
192
+ console.log(`点击位置: (${position.point.x}, ${position.point.y})`);
193
+ },
194
+ performScroll: (from: Position, to: Position) => {
195
+ console.log(`滚动: 从 (${from.point.x}, ${from.point.y}) 到 (${to.point.x}, ${to.point.y})`);
196
+ }
197
+ };
198
+
199
+ const simpleHandler = new SimpleInteractionHandler(player, listener);
200
+ ```
201
+
202
+ ### 示例 4: 手动创建控制消息
203
+
204
+ ```typescript
205
+ import {
206
+ TouchControlMessage,
207
+ Position,
208
+ Point,
209
+ Size,
210
+ MotionEvent
211
+ } from 'interaction-system';
212
+
213
+ // 模拟触摸按下
214
+ function simulateTouch(x: number, y: number) {
215
+ const message = new TouchControlMessage(
216
+ MotionEvent.ACTION_DOWN,
217
+ 0, // 指针 ID
218
+ new Position(
219
+ new Point(x, y),
220
+ new Size(1080, 1920)
221
+ ),
222
+ 1.0, // 压力值
223
+ MotionEvent.BUTTON_PRIMARY
224
+ );
225
+
226
+ const buffer = message.toBuffer();
227
+ return buffer;
228
+ }
229
+
230
+ // 发送到服务器
231
+ const touchBuffer = simulateTouch(540, 960);
232
+ ```
233
+
234
+ ## 构建工具配置
235
+
236
+ ### Vite 配置
237
+
238
+ 如果遇到 PNG 图片导入错误,配置 `vite.config.ts`:
239
+
240
+ ```typescript
241
+ import { defineConfig } from 'vite';
242
+
243
+ export default defineConfig({
244
+ assetsInclude: ['**/*.png'],
245
+ resolve: {
246
+ alias: {
247
+ 'interaction-system': require.resolve('interaction-system')
248
+ }
249
+ }
250
+ });
251
+ ```
252
+
253
+ ### Webpack 配置
254
+
255
+ 在 `webpack.config.js` 中:
256
+
257
+ ```javascript
258
+ module.exports = {
259
+ module: {
260
+ rules: [
261
+ {
262
+ test: /\.(png|jpg|gif)$/,
263
+ type: 'asset/resource'
264
+ }
265
+ ]
266
+ },
267
+ resolve: {
268
+ extensions: ['.ts', '.tsx', '.js']
269
+ }
270
+ };
271
+ ```
272
+
273
+ ### TypeScript 配置
274
+
275
+ 确保 `tsconfig.json` 包含:
276
+
277
+ ```json
278
+ {
279
+ "compilerOptions": {
280
+ "esModuleInterop": true,
281
+ "allowSyntheticDefaultImports": true,
282
+ "moduleResolution": "node",
283
+ "resolveJsonModule": true
284
+ }
285
+ }
286
+ ```
287
+
288
+ ## API 参考
289
+
290
+ ### 交互处理器
291
+
292
+ #### FeaturedInteractionHandler
293
+
294
+ 完整功能的交互处理器。
295
+
296
+ **构造函数:**
297
+ ```typescript
298
+ constructor(player: IPlayer, listener: InteractionHandlerListener)
299
+ ```
300
+
301
+ **支持的事件:**
302
+ - 鼠标点击、移动、抬起
303
+ - 触摸开始、移动、结束
304
+ - 鼠标滚轮
305
+ - 键盘按键
306
+ - 多点触控(Ctrl + 鼠标)
307
+
308
+ **多点触控:**
309
+ - `Ctrl + 鼠标移动` - 创建对称的两个触摸点
310
+ - `Ctrl + Shift + 鼠标` - 以首次点击为中心创建镜像触摸点
311
+
312
+ #### SimpleInteractionHandler
313
+
314
+ 简化版交互处理器。
315
+
316
+ **构造函数:**
317
+ ```typescript
318
+ constructor(player: IPlayer, listener: TouchHandlerListener)
319
+ ```
320
+
321
+ **支持的操作:**
322
+ - 点击(短距离拖动)
323
+ - 滚动(长距离拖动)
324
+
325
+ ### 键盘处理
326
+
327
+ #### KeyInputHandler
328
+
329
+ 全局键盘事件处理器。
330
+
331
+ **方法:**
332
+ ```typescript
333
+ // 添加监听器
334
+ static addEventListener(listener: KeyEventListener): void
335
+
336
+ // 移除监听器
337
+ static removeEventListener(listener: KeyEventListener): void
338
+ ```
339
+
340
+ ### 数据模型
341
+
342
+ #### Point
343
+ ```typescript
344
+ class Point {
345
+ constructor(x: number, y: number)
346
+ x: number
347
+ y: number
348
+ distance(to: Point): number
349
+ }
350
+ ```
351
+
352
+ #### Size
353
+ ```typescript
354
+ class Size {
355
+ constructor(width: number, height: number)
356
+ width: number
357
+ height: number
358
+ rotate(): Size
359
+ }
360
+ ```
361
+
362
+ #### Position
363
+ ```typescript
364
+ class Position {
365
+ constructor(point: Point, screenSize: Size)
366
+ point: Point
367
+ screenSize: Size
368
+ rotate(rotation: number): Position
369
+ }
370
+ ```
371
+
372
+ #### ScreenInfo
373
+ ```typescript
374
+ class ScreenInfo {
375
+ constructor(
376
+ contentRect: Rect,
377
+ videoSize: Size,
378
+ deviceRotation: number
379
+ )
380
+ static fromBuffer(buffer: Buffer): ScreenInfo
381
+ }
382
+ ```
383
+
384
+ ### 控制消息
385
+
386
+ 所有控制消息都继承自 `ControlMessage` 并实现:
387
+
388
+ ```typescript
389
+ abstract class ControlMessage {
390
+ toBuffer(): Buffer // 序列化为 Buffer
391
+ toString(): string // 转换为可读字符串
392
+ toJSON(): object // 转换为 JSON 对象
393
+ }
394
+ ```
395
+
396
+ ## 常见问题
397
+
398
+ ### Q: 如何调试控制消息?
399
+
400
+ A: 所有消息都实现了 `toString()` 和 `toJSON()` 方法:
401
+
402
+ ```typescript
403
+ listener: {
404
+ sendMessage: (msg) => {
405
+ console.log('消息类型:', msg.type);
406
+ console.log('可读格式:', msg.toString());
407
+ console.log('JSON:', JSON.stringify(msg.toJSON(), null, 2));
408
+ console.log('Buffer:', msg.toBuffer());
409
+ }
410
+ }
411
+ ```
412
+
413
+ ### Q: 如何处理图片资源错误?
414
+
415
+ A: 图片仅用于多点触控可视化。如果遇到导入错误:
416
+
417
+ 1. **配置构建工具**(推荐)- 参见[构建工具配置](#构建工具配置)
418
+ 2. **忽略错误** - 功能仍正常,只是没有图片显示
419
+
420
+ ### Q: 如何获取实时坐标?
421
+
422
+ A: 在消息监听器中获取:
423
+
424
+ ```typescript
425
+ sendMessage: (message) => {
426
+ if (message instanceof TouchControlMessage) {
427
+ const { x, y } = message.position.point;
428
+ console.log(`坐标: (${x}, ${y})`);
429
+ }
430
+ }
431
+ ```
432
+
433
+ ### Q: 如何禁用多点触控?
434
+
435
+ A: 多点触控需要按住 Ctrl 键才激活,用户不按就不会触发。
436
+
437
+ ### Q: 如何清理资源?
438
+
439
+ A: 调用 `release()` 方法:
440
+
441
+ ```typescript
442
+ // 创建
443
+ const handler = new FeaturedInteractionHandler(player, listener);
444
+
445
+ // 清理
446
+ handler.release();
447
+
448
+ // 键盘监听器
449
+ KeyInputHandler.removeEventListener(listener);
450
+ ```
451
+
452
+ ### Q: 能否在移动端使用?
453
+
454
+ A: 可以。`FeaturedInteractionHandler` 自动处理触摸事件,在移动设备上会使用原生触摸事件。
455
+
456
+ ### Q: 如何修改键盘映射?
457
+
458
+ A: 键盘映射定义在 `KeyToCodeMap` 中。如需自定义,可以创建新的 Map:
459
+
460
+ ```typescript
461
+ import { KeyEvent } from 'interaction-system';
462
+
463
+ const customMap = new Map([
464
+ ['KeyA', KeyEvent.KEYCODE_A],
465
+ // ... 添加更多映射
466
+ ]);
467
+ ```
468
+
469
+ ### Q: 支持哪些浏览器?
470
+
471
+ A: 支持所有现代浏览器:
472
+ - Chrome/Edge 90+
473
+ - Firefox 88+
474
+ - Safari 14+
475
+ - 移动浏览器(iOS Safari, Chrome Mobile)
476
+
477
+ ### Q: TypeScript 类型定义在哪里?
478
+
479
+ A: 包自带完整的类型定义文件(`.d.ts`),会被 TypeScript 自动识别。
480
+
481
+ ## 更多帮助
482
+
483
+ - [README.md](README.md) - 项目概览和快速开始
484
+ - [examples/](examples/) - 完整示例项目
485
+ - [GitHub Issues](https://github.com/NetrisTV/ws-scrcpy/issues) - 报告问题
486
+
487
+ ## 贡献
488
+
489
+ 欢迎提交 Issue 和 Pull Request!
490
+