@sketch-ruler/core 3.0.0-beta.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 (43) hide show
  1. package/AGENTS.md +145 -0
  2. package/README.md +230 -0
  3. package/lib/engine/coordinate.d.ts +38 -0
  4. package/lib/engine/coordinate.d.ts.map +1 -0
  5. package/lib/engine/index.d.ts +7 -0
  6. package/lib/engine/index.d.ts.map +1 -0
  7. package/lib/engine/matrix.d.ts +45 -0
  8. package/lib/engine/matrix.d.ts.map +1 -0
  9. package/lib/engine/minimap-engine.d.ts +64 -0
  10. package/lib/engine/minimap-engine.d.ts.map +1 -0
  11. package/lib/engine/transform-engine.d.ts +78 -0
  12. package/lib/engine/transform-engine.d.ts.map +1 -0
  13. package/lib/index.cjs +1 -0
  14. package/lib/index.d.ts +23 -0
  15. package/lib/index.d.ts.map +1 -0
  16. package/lib/index.iife.js +1 -0
  17. package/lib/index.js +950 -0
  18. package/lib/index.umd.cjs +1 -0
  19. package/lib/managers/canvas-manager.d.ts +61 -0
  20. package/lib/managers/canvas-manager.d.ts.map +1 -0
  21. package/lib/plugins/index.d.ts +2 -0
  22. package/lib/plugins/index.d.ts.map +1 -0
  23. package/lib/plugins/plugin-manager.d.ts +33 -0
  24. package/lib/plugins/plugin-manager.d.ts.map +1 -0
  25. package/lib/scale/index.d.ts +18 -0
  26. package/lib/scale/index.d.ts.map +1 -0
  27. package/lib/scale/tick-config.d.ts +15 -0
  28. package/lib/scale/tick-config.d.ts.map +1 -0
  29. package/lib/snap/snap-engine.d.ts +50 -0
  30. package/lib/snap/snap-engine.d.ts.map +1 -0
  31. package/lib/state/index.d.ts +3 -0
  32. package/lib/state/index.d.ts.map +1 -0
  33. package/lib/state/line-manager.d.ts +20 -0
  34. package/lib/state/line-manager.d.ts.map +1 -0
  35. package/lib/state/ruler-state.d.ts +49 -0
  36. package/lib/state/ruler-state.d.ts.map +1 -0
  37. package/lib/types/index.d.ts +164 -0
  38. package/lib/types/index.d.ts.map +1 -0
  39. package/lib/utils/id-utils.d.ts +3 -0
  40. package/lib/utils/id-utils.d.ts.map +1 -0
  41. package/lib/utils/line-utils.d.ts +40 -0
  42. package/lib/utils/line-utils.d.ts.map +1 -0
  43. package/package.json +66 -0
package/AGENTS.md ADDED
@@ -0,0 +1,145 @@
1
+ # @sketch-ruler/core 项目指南
2
+
3
+ > 本文件面向 AI Coding Agent,用于快速理解 `@sketch-ruler/core` 的结构、API 与开发约定。
4
+
5
+ ---
6
+
7
+ ## 包概述
8
+
9
+ `@sketch-ruler/core` 是 **框架无关** 的核心层,零外部依赖。负责:
10
+
11
+ - 坐标变换引擎(TransformEngine)
12
+ - 矩阵运算与坐标转换
13
+ - 刻度计算与配置
14
+ - 参考线状态管理(LineManager)
15
+ - 多画布管理器(CanvasManager)
16
+ - 插件系统(PluginManager)
17
+ - 吸附引擎(SnapEngine)
18
+ - Minimap 引擎(MinimapEngine)
19
+
20
+ ---
21
+
22
+ ## 目录结构
23
+
24
+ ```
25
+ src/
26
+ ├── engine/ # 变换引擎、矩阵、坐标转换、Minimap 引擎
27
+ │ ├── transform-engine.ts
28
+ │ ├── matrix.ts
29
+ │ ├── coordinate.ts
30
+ │ ├── minimap-engine.ts
31
+ │ └── index.ts
32
+ ├── state/ # 状态管理(RulerState、LineManager)
33
+ │ ├── ruler-state.ts
34
+ │ ├── line-manager.ts
35
+ │ └── index.ts
36
+ ├── managers/ # 多画布管理器
37
+ │ └── canvas-manager.ts
38
+ ├── plugins/ # 插件系统
39
+ │ ├── plugin-manager.ts
40
+ │ └── index.ts
41
+ ├── scale/ # 刻度计算
42
+ │ ├── tick-config.ts
43
+ │ └── index.ts
44
+ ├── snap/ # 吸附引擎
45
+ │ └── snap-engine.ts
46
+ ├── types/ # 框架无关的纯类型定义
47
+ │ └── index.ts
48
+ ├── utils/ # ID 生成、线段工具函数
49
+ │ ├── id-utils.ts
50
+ │ └── line-utils.ts
51
+ └── index.ts # 统一导出入口
52
+ ```
53
+
54
+ ---
55
+
56
+ ## 构建与测试
57
+
58
+ ```bash
59
+ # 安装依赖(在根目录执行)
60
+ pnpm i
61
+
62
+ # 构建本包
63
+ cd packages/core && pnpm build
64
+
65
+ # 运行测试
66
+ cd packages/core && pnpm test
67
+
68
+ # 测试监听模式
69
+ cd packages/core && pnpm test:watch
70
+ ```
71
+
72
+ ---
73
+
74
+ ## 编码约定
75
+
76
+ - **语言**:TypeScript 5.9+,strict 模式
77
+ - **模块**:ESM(`"type": "module"`)
78
+ - **DOM 依赖**:引擎层(`engine/`)**禁止**直接操作 DOM;DOM 相关逻辑由 `@sketch-ruler/canvas` 处理
79
+ - **命名**:
80
+ - 类名:PascalCase(`TransformEngine`、`CanvasManager`)
81
+ - 类型/接口:PascalCase,以 `Type` 或 `Options` 结尾(`TransformState`、`TransformEngineOptions`)
82
+ - 纯工具函数:camelCase(`importLines`、`exportLines`)
83
+ - **导出风格**:`index.ts` 按模块分类导出,类型与实现分离(`export` / `export type`)
84
+
85
+ ---
86
+
87
+ ## 关键 API 速查
88
+
89
+ ### TransformEngine
90
+
91
+ ```ts
92
+ const engine = new TransformEngine(
93
+ { x: 0, y: 0, scale: 1 },
94
+ { minZoom: 0.1, maxZoom: 10, enableAnimation: true, animationMode: 'ease-out' }
95
+ )
96
+ engine.onUpdate((state) => { ... }) // 订阅状态
97
+ engine.zoomBy(dScale, originX, originY) // 相对缩放
98
+ engine.zoomTo(scale, originX, originY) // 绝对缩放
99
+ engine.panBy(dx, dy) // 相对平移
100
+ engine.setTransform({ scale, x, y }) // 直接设置
101
+ engine.destroy()
102
+ ```
103
+
104
+ ### CanvasManager
105
+
106
+ ```ts
107
+ const manager = new CanvasManager([...])
108
+ manager.onUpdate((state) => { ... })
109
+ manager.addCanvas(config)
110
+ manager.switchCanvas(id)
111
+ manager.removeCanvas(id)
112
+ manager.updateCanvasState(id, { scale, offsetX, offsetY })
113
+ manager.updateCanvasLines(id, importLines({ h, v }))
114
+ ```
115
+
116
+ ### 参考线格式转换
117
+
118
+ - `importLines({ h, v })` — `{h, v}` → `GuideLine[]`
119
+ - `exportLines(guideLines)` — `GuideLine[]` → `{h, v}`
120
+
121
+ ### 矩阵与坐标
122
+
123
+ - `fromTransform(scale, x, y)` → `Matrix6`
124
+ - `toWorldPoint(matrix, screenX, screenY)` — 屏幕 → 世界
125
+ - `toScreenPoint(matrix, worldX, worldY)` — 世界 → 屏幕
126
+
127
+ ---
128
+
129
+ ## 子路径导出
130
+
131
+ | 路径 | 用途 |
132
+ |------|------|
133
+ | `@sketch-ruler/core` | 完整导出 |
134
+ | `@sketch-ruler/core/engine` | 仅引擎层(TransformEngine、矩阵、坐标) |
135
+ | `@sketch-ruler/core/state` | 仅状态管理 |
136
+ | `@sketch-ruler/core/plugins` | 仅插件系统 |
137
+ | `@sketch-ruler/core/scale` | 仅刻度计算 |
138
+
139
+ ---
140
+
141
+ ## 注意事项
142
+
143
+ - `TransformEngine` 的所有坐标计算基于 **左上角原点** (`0, 0`),外部 CSS 需要配合 `transform-origin: 0 0`
144
+ - `CanvasManager` 的 `lines` 字段存储的是内部 `GuideLine[]` 格式,与 SketchRuler 组件的 `{h, v}` 格式需通过 `importLines` / `exportLines` 转换
145
+ - 新增模块时,请在 `src/index.ts` 中按分类添加导出
package/README.md ADDED
@@ -0,0 +1,230 @@
1
+ # @sketch-ruler/core
2
+
3
+ > 框架无关的核心层:坐标变换引擎、多画布管理、参考线状态、吸附引擎、Minimap 引擎、刻度计算等。零外部依赖。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install @sketch-ruler/core
9
+ # 或
10
+ pnpm add @sketch-ruler/core
11
+ ```
12
+
13
+ ## 快速上手
14
+
15
+ ### TransformEngine — 2D 变换引擎
16
+
17
+ 维护缩放/平移状态,内置多种动画插值模式。
18
+
19
+ ```ts
20
+ import { TransformEngine } from '@sketch-ruler/core'
21
+
22
+ const engine = new TransformEngine(
23
+ { x: 0, y: 0, scale: 1 }, // 初始状态
24
+ { minZoom: 0.1, maxZoom: 10, enableAnimation: true, animationMode: 'ease-out' }
25
+ )
26
+
27
+ // 监听状态变化(注册时立即回调一次当前状态)
28
+ const unsubscribe = engine.onUpdate((state) => {
29
+ console.log('scale', state.scale, 'offset', state.x, state.y)
30
+ })
31
+
32
+ // 以屏幕坐标 (400, 300) 为原点放大 0.5
33
+ engine.zoomBy(0.5, 400, 300)
34
+
35
+ // 缩放到指定比例
36
+ engine.zoomTo(2, 400, 300)
37
+
38
+ // 平移
39
+ engine.panBy(100, -50)
40
+
41
+ // 直接设置
42
+ engine.setTransform({ scale: 1, x: 0, y: 0 })
43
+
44
+ // 坐标转换
45
+ const world = engine.toWorldPoint(100, 100) // 屏幕 → 世界
46
+ const screen = engine.toScreenPoint(50, 50) // 世界 → 屏幕
47
+
48
+ // 清理
49
+ unsubscribe()
50
+ engine.destroy()
51
+ ```
52
+
53
+ ### CanvasManager — 多画布管理器
54
+
55
+ 管理多个画布配置,支持模板、切换、导入导出。
56
+
57
+ ```ts
58
+ import { CanvasManager, BUILTIN_TEMPLATES, exportLines, importLines } from '@sketch-ruler/core'
59
+
60
+ const manager = new CanvasManager([
61
+ { name: '首页', width: 1920, height: 1080, lines: { h: [100], v: [200] } },
62
+ { name: '详情页', width: 375, height: 812 }
63
+ ])
64
+
65
+ // 监听状态变化
66
+ manager.onUpdate((state) => {
67
+ console.log('当前画布:', state.activeId, '总数:', state.canvases.length)
68
+ })
69
+
70
+ // 应用内置模板
71
+ const id = manager.applyTemplate('A4 Portrait')
72
+
73
+ // 切换画布(自动保存缩略图)
74
+ manager.switchCanvas(id)
75
+
76
+ // 更新当前画布的缩放与偏移
77
+ manager.updateCanvasState(id, { scale: 0.8, offsetX: 100, offsetY: 50 })
78
+
79
+ // 更新参考线(SketchRuler 发出的是 {h, v},需先 importLines)
80
+ manager.updateCanvasLines(id, importLines({ h: [0, 250], v: [0, 500] }))
81
+
82
+ // 导出参考线(转回 {h, v} 给 SketchRuler)
83
+ const canvas = manager.activeCanvas
84
+ if (canvas) {
85
+ const lines = exportLines(canvas.lines) // => { h: number[], v: number[] }
86
+ }
87
+
88
+ // 删除画布
89
+ manager.removeCanvas(id)
90
+ ```
91
+
92
+ ### 插件系统 — PluginManager
93
+
94
+ ```ts
95
+ import { PluginManager } from '@sketch-ruler/core'
96
+ import type { SketchRulerPlugin } from '@sketch-ruler/core'
97
+
98
+ const pluginManager = new PluginManager()
99
+
100
+ const myPlugin: SketchRulerPlugin = {
101
+ name: 'logger',
102
+ beforeZoom: (ctx) => {
103
+ console.log('zoom from', ctx.from, 'to', ctx.to)
104
+ return true // return false 可阻止缩放
105
+ },
106
+ onLineCreate: (ctx) => console.log('line created', ctx.line.id),
107
+ onLineDelete: (ctx) => console.log('line deleted', ctx.line.id)
108
+ }
109
+
110
+ pluginManager.register(myPlugin)
111
+ ```
112
+
113
+ ### 吸附引擎 — SnapEngine
114
+
115
+ ```ts
116
+ import { SnapEngine } from '@sketch-ruler/core'
117
+
118
+ const snapEngine = new SnapEngine({ threshold: 5 })
119
+
120
+ const result = snapEngine.snap({
121
+ x: 102,
122
+ y: 198,
123
+ targets: [
124
+ { type: 'line', orientation: 'h', value: 100 },
125
+ { type: 'line', orientation: 'v', value: 200 }
126
+ ]
127
+ })
128
+
129
+ if (result.snapped) {
130
+ console.log('吸附到', result.x, result.y)
131
+ }
132
+ ```
133
+
134
+ ### MinimapEngine — 缩略图导航引擎
135
+
136
+ ```ts
137
+ import { MinimapEngine, MinimapDragSession } from '@sketch-ruler/core'
138
+
139
+ const engine = new MinimapEngine({
140
+ contentWidth: 1920,
141
+ contentHeight: 1080,
142
+ viewportWidth: 1470,
143
+ viewportHeight: 700
144
+ })
145
+
146
+ // 更新视口状态
147
+ engine.updateViewport({ x: 100, y: 50, scale: 0.5 })
148
+
149
+ // 计算视口在缩略图中的矩形
150
+ const rect = engine.getViewportRect(200, 150)
151
+
152
+ // 拖拽会话
153
+ const session = engine.startDrag(50, 50)
154
+ const newPos = session.move(60, 60)
155
+ engine.endDrag()
156
+ ```
157
+
158
+ ### 参考线工具函数
159
+
160
+ ```ts
161
+ import { importLines, exportLines, computeLineStyle } from '@sketch-ruler/core'
162
+ import type { GuideLine } from '@sketch-ruler/core'
163
+
164
+ // SketchRuler {h, v} → 内部 GuideLine[]
165
+ const guideLines: GuideLine[] = importLines({ h: [0, 250], v: [0, 500] })
166
+
167
+ // 内部 GuideLine[] → SketchRuler {h, v}
168
+ const lines = exportLines(guideLines) // { h: [0, 250], v: [0, 500] }
169
+
170
+ // 计算参考线在 DOM 中的样式
171
+ const style = computeLineStyle(guideLines[0], 1, 0, false, '#51d6a9')
172
+ ```
173
+
174
+ ### 矩阵与坐标工具
175
+
176
+ ```ts
177
+ import {
178
+ createMatrix, fromTransform, multiply, invert, toCSSString,
179
+ toWorldPoint, toScreenPoint, fitRect
180
+ } from '@sketch-ruler/core'
181
+
182
+ // 从变换状态生成矩阵
183
+ const matrix = fromTransform(1.5, 100, 50)
184
+
185
+ // 转 CSS matrix 字符串
186
+ const css = toCSSString(matrix) // "matrix(1.5, 0, 0, 1.5, 100, 50)"
187
+
188
+ // 屏幕坐标 → 世界坐标
189
+ const world = toWorldPoint(matrix, 200, 200)
190
+
191
+ // 将内容矩形适配到视口
192
+ const fitted = fitRect({ width: 1920, height: 1080 }, { width: 1470, height: 700 }, 0.2)
193
+ ```
194
+
195
+ ### 刻度计算
196
+
197
+ ```ts
198
+ import { computeScaleMarks, getTickConfig, applyHysteresis } from '@sketch-ruler/core'
199
+
200
+ const marks = computeScaleMarks({
201
+ scale: 1,
202
+ offset: 0,
203
+ length: 800,
204
+ thick: 20,
205
+ config: getTickConfig(1)
206
+ })
207
+
208
+ // 应用滞回避免频繁跳变
209
+ const stableConfig = applyHysteresis(0.85, getTickConfig(0.8), getTickConfig(1))
210
+ ```
211
+
212
+ ## API 概览
213
+
214
+ | 模块 | 导出 | 说明 |
215
+ |------|------|------|
216
+ | `TransformEngine` | 类 | 2D 仿射变换引擎,支持动画 |
217
+ | `CanvasManager` | 类 | 多画布生命周期管理 |
218
+ | `BUILTIN_TEMPLATES` | 常量 | 内置画布模板(A4、Web 1920、Mobile 等) |
219
+ | `PluginManager` | 类 | 插件注册与生命周期调度 |
220
+ | `SnapEngine` | 类 | 参考线吸附计算 |
221
+ | `MinimapEngine` | 类 | 缩略图视口映射与拖拽 |
222
+ | `LineManager` | 类 | 参考线增删改查 |
223
+ | `importLines` / `exportLines` | 函数 | 参考线格式转换 |
224
+ | `computeLineStyle` | 函数 | 参考线 DOM 样式计算 |
225
+ | `computeScaleMarks` | 函数 | 刻度标记计算 |
226
+ | `fromTransform` / `toWorldPoint` / `toScreenPoint` | 函数 | 矩阵与坐标转换 |
227
+
228
+ ## License
229
+
230
+ MIT
@@ -0,0 +1,38 @@
1
+ import { Matrix6 } from './matrix';
2
+ export interface Point {
3
+ x: number;
4
+ y: number;
5
+ }
6
+ export interface Rect {
7
+ x: number;
8
+ y: number;
9
+ width: number;
10
+ height: number;
11
+ }
12
+ /**
13
+ * 屏幕坐标 → 世界坐标
14
+ */
15
+ export declare function toWorldPoint(matrix: Matrix6, screenX: number, screenY: number): Point;
16
+ /**
17
+ * 世界坐标 → 屏幕坐标
18
+ */
19
+ export declare function toScreenPoint(matrix: Matrix6, worldX: number, worldY: number): Point;
20
+ /**
21
+ * 批量屏幕坐标 → 世界坐标
22
+ */
23
+ export declare function batchToWorld(matrix: Matrix6, points: Point[]): Point[];
24
+ /**
25
+ * 批量世界坐标 → 屏幕坐标
26
+ */
27
+ export declare function batchToScreen(matrix: Matrix6, points: Point[]): Point[];
28
+ /**
29
+ * Fit 矩形到目标矩形
30
+ * @param mode 'contain' | 'cover' | 'center'
31
+ * @param paddingRatio 边距比例(默认 0,即不留边距)
32
+ */
33
+ export declare function fitRect(source: Rect, target: Rect, mode?: 'contain' | 'cover' | 'center', paddingRatio?: number): {
34
+ scale: number;
35
+ x: number;
36
+ y: number;
37
+ };
38
+ //# sourceMappingURL=coordinate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate.d.ts","sourceRoot":"","sources":["../../src/engine/coordinate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEvC,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAcrF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAKpF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAEtE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,IAAI,EACZ,IAAI,GAAE,SAAS,GAAG,OAAO,GAAG,QAAoB,EAChD,YAAY,SAAI,GACf;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CA4BzC"}
@@ -0,0 +1,7 @@
1
+ export { createMatrix, fromTransform, multiply, invert, decompose, toCSSString, equals } from './matrix';
2
+ export type { Matrix6 } from './matrix';
3
+ export { toWorldPoint, toScreenPoint, batchToWorld, batchToScreen, fitRect } from './coordinate';
4
+ export type { Point, Rect } from './coordinate';
5
+ export { TransformEngine } from './transform-engine';
6
+ export type { TransformState, TransformEngineOptions, TransformUpdateCallback } from './transform-engine';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,MAAM,EACN,SAAS,EACT,WAAW,EACX,MAAM,EACP,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAChG,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * 2D 仿射变换矩阵运算
3
+ * 使用 Float64Array(6) 紧凑存储: [a, b, c, d, e, f]
4
+ * 对应变换矩阵:
5
+ * | a c e |
6
+ * | b d f |
7
+ * | 0 0 1 |
8
+ *
9
+ * 零 DOM 依赖,纯数学运算,可在 Node.js 环境直接测试
10
+ */
11
+ export type Matrix6 = Float64Array;
12
+ /**
13
+ * 创建单位矩阵
14
+ */
15
+ export declare function createMatrix(): Matrix6;
16
+ /**
17
+ * 从缩放和平移参数创建矩阵
18
+ */
19
+ export declare function fromTransform(scale: number, x: number, y: number): Matrix6;
20
+ /**
21
+ * 矩阵乘法: result = a * b
22
+ */
23
+ export declare function multiply(a: Matrix6, b: Matrix6): Matrix6;
24
+ /**
25
+ * 求逆矩阵
26
+ */
27
+ export declare function invert(m: Matrix6): Matrix6 | null;
28
+ /**
29
+ * 分解矩阵为 scale, x, y
30
+ * 假设无旋转和倾斜(sketch-ruler 场景)
31
+ */
32
+ export declare function decompose(m: Matrix6): {
33
+ scale: number;
34
+ translateX: number;
35
+ translateY: number;
36
+ };
37
+ /**
38
+ * 转换为 CSS transform string
39
+ */
40
+ export declare function toCSSString(m: Matrix6): string;
41
+ /**
42
+ * 判断两个矩阵是否相等(考虑浮点误差)
43
+ */
44
+ export declare function equals(a: Matrix6, b: Matrix6, epsilon?: number): boolean;
45
+ //# sourceMappingURL=matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../src/engine/matrix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,OAAO,GAAG,YAAY,CAAA;AAElC;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CASxD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAejD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAM/F;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,SAAO,GAAG,OAAO,CAOtE"}
@@ -0,0 +1,64 @@
1
+ export interface MinimapOptions {
2
+ contentWidth: number;
3
+ contentHeight: number;
4
+ viewportX: number;
5
+ viewportY: number;
6
+ viewportWidth: number;
7
+ viewportHeight: number;
8
+ scale: number;
9
+ width: number;
10
+ height: number;
11
+ }
12
+ export interface MinimapState {
13
+ miniScale: number;
14
+ contentOffset: {
15
+ x: number;
16
+ y: number;
17
+ };
18
+ viewportRect: {
19
+ left: number;
20
+ top: number;
21
+ width: number;
22
+ height: number;
23
+ };
24
+ }
25
+ export interface DragSessionState {
26
+ targetX: number;
27
+ targetY: number;
28
+ dragRect: {
29
+ left: number;
30
+ top: number;
31
+ width: number;
32
+ height: number;
33
+ };
34
+ }
35
+ export declare class MinimapEngine {
36
+ private options;
37
+ constructor(options: MinimapOptions);
38
+ getState(): MinimapState;
39
+ clampTransform(x: number, y: number): {
40
+ x: number;
41
+ y: number;
42
+ };
43
+ canPan(): boolean;
44
+ clickAt(clientX: number, clientY: number, rectLeft: number, rectTop: number): {
45
+ x: number;
46
+ y: number;
47
+ };
48
+ startDrag(startViewportX: number, startViewportY: number, startMinimapLeft: number, startMinimapTop: number): MinimapDragSession;
49
+ }
50
+ export declare class MinimapDragSession {
51
+ private engine;
52
+ private startViewportX;
53
+ private startViewportY;
54
+ private startMinimapLeft;
55
+ private startMinimapTop;
56
+ private ratio;
57
+ constructor(engine: MinimapEngine, startViewportX: number, startViewportY: number, startMinimapLeft: number, startMinimapTop: number);
58
+ move(accDx: number, accDy: number): DragSessionState;
59
+ end(accDx: number, accDy: number): {
60
+ x: number;
61
+ y: number;
62
+ };
63
+ }
64
+ //# sourceMappingURL=minimap-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimap-engine.d.ts","sourceRoot":"","sources":["../../src/engine/minimap-engine.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACvC,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3E;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CACvE;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE3C,QAAQ,IAAI,YAAY;IAsBxB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAsB9D,MAAM,IAAI,OAAO;IAOjB,OAAO,CACL,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAS3B,SAAS,CACP,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,GACtB,kBAAkB;CAStB;AAED,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,eAAe;IAPzB,OAAO,CAAC,KAAK,CAAQ;gBAGX,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM;IAKjC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB;IAsBpD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;CAM5D"}
@@ -0,0 +1,78 @@
1
+ import { Matrix6 } from './matrix';
2
+ export interface TransformState {
3
+ x: number;
4
+ y: number;
5
+ scale: number;
6
+ }
7
+ export type AnimationMode = 'direct' | 'ease-out' | 'damped' | 'exponential';
8
+ export interface TransformEngineOptions {
9
+ minZoom?: number;
10
+ maxZoom?: number;
11
+ enableAnimation?: boolean;
12
+ animationDuration?: number;
13
+ animationMode?: AnimationMode;
14
+ /** 阻尼系数(damped 模式),默认 0.8 */
15
+ dampingRatio?: number;
16
+ /** 自然频率 rad/s(damped 模式),默认 20 */
17
+ naturalFrequency?: number;
18
+ /** 时间常数 ms(exponential 模式),默认 80 */
19
+ timeConstant?: number;
20
+ }
21
+ export type TransformUpdateCallback = (state: TransformState) => void;
22
+ export declare class TransformEngine {
23
+ private matrix;
24
+ private targetState;
25
+ private currentState;
26
+ private minZoom;
27
+ private maxZoom;
28
+ private enableAnimation;
29
+ private animationDuration;
30
+ private animationMode;
31
+ private dampingRatio;
32
+ private naturalFrequency;
33
+ private timeConstant;
34
+ private pendingTransform;
35
+ private rafId;
36
+ private callbacks;
37
+ private lastFrameTime;
38
+ private velocity;
39
+ constructor(initial?: TransformState, options?: TransformEngineOptions);
40
+ /** 注册更新回调 */
41
+ onUpdate(callback: TransformUpdateCallback): () => void;
42
+ /** 原子性设置变换状态 */
43
+ setTransform(t: Partial<TransformState>): void;
44
+ /** 相对平移 */
45
+ panBy(dx: number, dy: number): void;
46
+ /**
47
+ * 以指定原点为中心缩放
48
+ * @param dScale 缩放增量(相对当前 scale)
49
+ * @param originX 缩放原点屏幕坐标 X
50
+ * @param originY 缩放原点屏幕坐标 Y
51
+ */
52
+ zoomBy(dScale: number, originX: number, originY: number): void;
53
+ /** 缩放至目标比例 */
54
+ zoomTo(scale: number, originX: number, originY: number): void;
55
+ /** 屏幕坐标 → 世界坐标 */
56
+ toWorldPoint(screenX: number, screenY: number): {
57
+ x: number;
58
+ y: number;
59
+ };
60
+ /** 世界坐标 → 屏幕坐标 */
61
+ toScreenPoint(worldX: number, worldY: number): {
62
+ x: number;
63
+ y: number;
64
+ };
65
+ /** 获取当前状态 */
66
+ getState(): TransformState;
67
+ /** 获取当前变换矩阵 */
68
+ getMatrix(): Matrix6;
69
+ /** 销毁引擎,清理资源 */
70
+ destroy(): void;
71
+ private clampScale;
72
+ private updateMatrix;
73
+ private scheduleUpdate;
74
+ private onFrame;
75
+ private lerp;
76
+ private notify;
77
+ }
78
+ //# sourceMappingURL=transform-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform-engine.d.ts","sourceRoot":"","sources":["../../src/engine/transform-engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiD,KAAK,OAAO,EAAE,MAAM,UAAU,CAAA;AAGtF,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,aAAa,CAAA;AAE5E,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAA;AAErE,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,SAAS,CAA0C;IAE3D,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,QAAQ,CAA2B;gBAGzC,OAAO,GAAE,cAAyC,EAClD,OAAO,GAAE,sBAA2B;IAiBtC,aAAa;IACb,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,GAAG,MAAM,IAAI;IASvD,gBAAgB;IAChB,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IAoB9C,WAAW;IACX,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAanC;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAyB9D,cAAc;IACd,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK7D,kBAAkB;IAClB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAIxE,kBAAkB;IAClB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAIvE,aAAa;IACb,QAAQ,IAAI,cAAc;IAI1B,eAAe;IACf,SAAS,IAAI,OAAO;IAIpB,gBAAgB;IAChB,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,OAAO;IA+Ff,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,MAAM;CAIf"}